Why are atoi and strtol only returning the first number from my string most of the time?

StackOverflow https://stackoverflow.com/questions/15303677

  •  18-03-2022
  •  | 
  •  

Question

I'm trying to get ints from a c file that has input like this:

(0 3 200 3) (0 9 500 3) (98 20 500 3) (100 1 100 3) (100 100 500 3)

atoi and s work fine for the first number after the parenthesis (I use a while loop and strcat numbers larger than one digit) and any number that is only one digit, but they only return the first digit for numbers that are not right after the parenthesis.

Here is what the code for the method:

 void allProcesses(FILE file, struct process processArray[]) {
char ch;
int number;
int a, b, c, io;
int arrayCount = 0;
int processIndex = 0;
char temp[1];

while ((ch = fgetc(&file)) != EOF) {

    if (isdigit(ch)) {

        char numberAppended[20] = "";

        while (isdigit(ch)) {
            temp[0] = ch;
            strcat(numberAppended, temp);
            ch = fgetc(&file);
        }

        char* end;
        number = (int)strtol(numberAppended, &end, 0);
        printf("The number is %d\n",number);
        int atoinum = atoi(numberAppended);



        switch (processIndex) {
            case 0:
                a = number;
                if (DEBUG == TRUE) {
                    printf("a = %c\n", a);
                    printf("NUmber a is %d\n", a);
                }
                processIndex++;
                break;
            case 1:
                b = number;
                if (DEBUG == TRUE) {
                    printf("b = %c\n", b);
                    printf("NUmber b is %d\n", b);
                }
                processIndex++;
                break;
            case 2:
                c = number;
                if (DEBUG == TRUE) {
                    printf("c = %c\n", c);
                    printf("NUmber c is %d\n", c);
                }
                processIndex++;
                break;
            case 3:
                io = number;
                if (DEBUG == TRUE) {
                    printf("io = %c\n", io);
                    printf("NUmber io is %d\n", io);
                }
                processIndex++;
                break;
            default:
                break;
        }
    }
    if (ch == ')') {
        processArray[arrayCount] = makeProcess(a, b, c, io);
        arrayCount++;
        processIndex = 0;
    }

}

}

Was it helpful?

Solution

First (read comments):

you have declared char temp[1]; one size it has to be of size 2 according to your code(otherwise undefined behavior because memory overrun):

char temp[2];
while (isdigit(ch)) { // from `(` to `)`
   temp[0] = ch;   // should be a null terminated 
   temp[1] = '\0'; // add this step;
   strcat(numberAppended, temp); 
   ch = fgetc(&file);
}

Second: your numberAppended is parse to a string of kind: "0 9 500 3"
and your are calling

number = (int)strtol(numberAppended, &end, 0);
                                      ^
                                      output argument

syntax for strtol:

long int strtol(const char *numberAppended, char **end, int base);  

Where

  • numberAppended: is the string to be converted into a long integer.
  • end: points to a pointer that will be set to the character immediately following the long integer in the string "numberAppended".

And your are to write something like this: (read comments)

end = numberAppended;  // assign to first string
// in a loop {
number = (int)strtol(end, &end, 0);  // in loop end is input &end is output
printf("The number is %d\n",number); 
//}

My following code will help your to understand how to use strtol() to parse and extract number from numberAppended string:

#include <stdio.h>      /* printf */
#include <stdlib.h>     /* strtol */
int main (){
  char numberAppended[] = "2001 11 223   444   566";
  char * end;
  long int li;
  end =numberAppended;
  int base =10;
  int ele = 0;
  while(li=strtol (end, &end, base)){
     printf("%ld \n", li);
     ele += 1;
  }
  printf("\nNo of elements: %d", ele);
  return 0;
}

output:

2001 
11 
223 
444 
566 

No of elements: 5

third: may be its not an error but I couldn't find where processIndex updates in your code before switch(){}..

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top