0

im struggeling with a function. Goal is to check the user input (already sanitized) and act accordingly.

the function looks like this:

bool checkMove(board *Minesweeper,char *input){
  char *tmp;
  switch(input[0]){
    case '?':
      if(isalpha(input[1])){
        input[1]=toupper(input[1]);
        long eval = strtol(input, &tmp, 10);
        if(tmp==input){
          printf("something went wrong :(\n");
        }
        printf("Number: %ld\n",eval);

        if (eval>Minesweeper->height) {
          printf("Out of Bounds!\n");
        } else {
          printf("Valid move\n");
        }
// other stuff

The output:

Your Move: ?A21
something went wrong :(
Number: 0
Valid move

I'm passing the input values, so its not a local function. The same code (strtol) works in a different context just fine. I dont think its an issue with a local variable.

h1ghrise
  • 19
  • 4
  • The code seems correct; where do you look for a problem? – U. Windl Dec 21 '19 at 18:12
  • Is what is printed after "Your Move: " the value of `input`? – Saucy Goat Dec 21 '19 at 18:14
  • Hi, I want to convert the numbers in the input into an int. So I can work with them later on (conditional checks etc.) For example see the if statement where I compare eval (result of conversion) with the height of the game board.But if I cannot convert the numbers in the string, i cannot work with them. – h1ghrise Dec 21 '19 at 18:16
  • 1
    `input+2` has exactly the same meaning as `&input[2]`. – wallyk Dec 21 '19 at 18:19
  • @U.Windl "The code seems correct" -- No, really, it doesn't. – Jim Balter Dec 24 '19 at 00:14

2 Answers2

3

From the man pages:

"The strtol() function converts the initial part of the string..."

Your string starts with "?A", so the function fails. One solution would be to do the following instead:

long eval = strtol(input+2, &tmp, 10);

This way you "skip" the first 2 chars in input.

Saucy Goat
  • 1,587
  • 1
  • 11
  • 32
  • this worked very well. Can you explain what is meant with "initial part" ? I learnt that if you throw a string to strtol like `char[20] = "A2124B21"` strtol will split it into `2124` and the next in `21`. I dont get why my string `A?21` lets the function fail. Why isnt it converting the containing number? – h1ghrise Dec 21 '19 at 18:24
  • 1
    @h1ghrise "if you throw a string to strtol like char[20] = "A2124B21" strtol will split it into 2124 and the next in 21" --> No, it does not. – chux - Reinstate Monica Dec 21 '19 at 18:27
  • I don't think your learning source was very good then. The man pages are very clear about this: the string *must* start with a number else it will fail. Glad my answer helped. Cheers :) – Saucy Goat Dec 21 '19 at 18:27
  • 1
    @chux-ReinstateMonica yes. You are totally right. I was mistaken. Of course it converts only the _initial_ part. I get it now. Sorry for confusion. D'oh... – h1ghrise Dec 21 '19 at 18:28
  • 1
    Detail, the string can start with white-spaces, a sign character as well as digits to begin a successful conversion. – chux - Reinstate Monica Dec 21 '19 at 18:29
0

As many suggest, to start the numeric conversion, start from input + 2.

// long eval = strtol(input, &tmp, 10);
long eval = strtol(input + 2, &tmp, 10);

Prudent code would check first that the strict is at least length 2.

if (input[1]) {  // we know input[0] is a '?'`
  long eval = strtol(input + 2, &tmp, 10);

The later conversion check also needs amendment

  // if(tmp == input){
  if(tmp == input + 2) {
    printf("something went wrong :(\n");
  }
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256