tags:

views:

339

answers:

8

I have a program that allows the user to enter a level number, and then it plays that level:

char lvlinput[4];
std::cin.getline(lvlinput, 4)
char param_str[20] = "levelplayer.exe "
strcat_s(param_str, 20, lvlinput);
system(param_str);

And the level data is stored in folders \001, \002, \003, etc., etc. However, I have no way of telling whether the user entered three digits, ie: 1, 01, or 001. And all of the folders are listed as three digit numbers. I can't just check the length of the lvlinput string because it's an array, so How could I make sure the user entered three digits?

+7  A: 

You are really asking the wrong question. Investigate the C++ std::string class and then come back here.

anon
+9  A: 

Why not use std::string?
This makes storage, concatenation, and modification much easier.

If you need a c-style string after, use: my_string.c_str()

Here is a hint: To make your input 3 characters long, use std::insert to prefix your number with 0's.

Nick Presta
I don't need to make it three digits long, I just need to check if the user entered three digits.
Keand64
If you don't need to make the input any specific length, why do you care how many digits the user entered? Anyways, the first link I gave you should have size() to give you the string length.
Nick Presta
+2  A: 

What do you mean you can't check the length of the string? getline generates a NULL terminated c-string so just use strlen(lvlinput).

Gerald
lvlinput is already defined as having a length of 3, so whether the user inputs 3, 03, 003, or 0003, the length of lvlinput is always 3.
Keand64
How is lvlinput defined as having a length of 3? You should really take some time to read up on how strings work in C++.
Gerald
+3  A: 

Eh? Why do they need to enter 3 digits? Why not just pad it if they don't? If you really want to check that they entered 3 digits, use strlen. But what I recommend you do is atoi their input, and then sprintf(cmd, "levelplayer.exe %03d", lvlinput_as_integer)

Mark
A: 

Neil told you where you should start, your code might look like this.

std::string level, game = "levelplayer.exe ";

std::cout << "Enter the level number : ";
std::cin >> level;

if(level.size() != 3)
{
 // Error!
}
else
{
// if you have more processing, it goes here :) 
 game += level;
 std::system(game.c_str());
}
AraK
A: 

You can check the length of your NULL terminated string that getline returns by using:

int len = strlen(lvlinput);

This works because getline returns a NULL-terminated string.

However, this is besides the point to your problem. If you want to stay away from std::string (and there isn't any particular reason why you should in this case), then you should just convert the string to an integer, and use the integer to construct the command that goes to the system file:

char lvlinput[4];
std::cincin.getline(lvlinput, 4);
char param_str[20];
snprintf(param_str, 20, "levelplayer.exe %03d", atoi(lvlinput));
system(param_str);
Mark Santesson
+2  A: 

Here's how you could do this in C++:

std::string lvlinput;
std::getline(std::cin, lvlinput);
if (lvlinput.size() > 3) { // if the input is too long, there's nothing we can do
  throw std::exception("input string too long");
}
while (lvlinput.size() < 3) { // if it is too short, we can fix it by prepending zeroes
  lvlinput = "0" + lvlinput;
}
std::string param_str = "levelplayer.exe ";
param_str += lvlinput; 
system(param_str.c_str());

You've got a nice string class which takes care of concatenation, length and all those other fiddly things for you. So use it.

Note that I use std::getline instead of cin.getline. The latter writes the input to a char array, while the former writes to a proper string.

jalf
00003 should be a valid input though, and using a loop to pad doesn't seem right. internally it has to shift the whole string down each time you add a 0.
Mark
He didn't say 00003 should be a valid input, and you're right that the loop isn't efficient, but does it matter? The precise data validation is up to the OP. I simply showed how it could be approached, and how he should use C++ strings instead of char arrays.
jalf
@mark: I don't really care too much about validating every possible entry (I can do that already), I just had no idea how to check what the length of the string was before it got appended to the char array.
Keand64
A: 

This is the C++ solution to this problem, I think:

#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

void pad_string(std::string& str, char padChar, unsigned padSize)
{
    std::stringstream ss;
    ss << std::setfill(padChar) << std::setw(padSize) << str;

    str = ss.str();
}


int main()
{
    std::string levelNumber;
    std::cin >> levelNumber;

    pad_string(levelNumber, '0', 3);

    std::string levelString = "levelplayer.exe " + levelNumber;

    std::cout << levelString << std::endl;
}

Edit

This is a much more elegant way of implementing pad_string:

void pad_string(std::string& str, char padChar, unsigned padSize)
{
    if (str.length() < 3)
    {
     str.insert(0, padSize - str.length(), padChar);
    }
}
GMan