Search code examples
catoistrtol

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


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;
    }

}

}


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(){}..