#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    14
    Rep Power
    0

    Unhappy Convert a char array into an int array in C


    Hello,

    Please, I read a text file containing random numbers into a char buffer by doing this :
    Code:
    FILE *fp;
       char buff[200000];
       int buffInt[200000];
       int i = 0;
    
       fp = fopen("input.txt", "r");
       if( fp != NULL ){
          while ( !feof(fp ) ){
             memset(buff, '\0', sizeof( buff) );
             fgets(buff, 255, (FILE*)fp);
             if(i>200000) break;
             else{
             buffInt[i] = atoi(buff); //important line..
             i++;
             }
             //printf("%s", buff);
          }
          fclose(fp);
    This text file (input.txt) contains some random numbers like i said earlier. below is an example of how these numbers are listed:

    39555
    76914
    62328
    96066
    78739
    31842
    83766
    18474
    86578
    78136
    71620
    61066
    63789
    2824
    .....


    This works fine with the char buff declared but I want to convert each element into an integer but the line
    buffInt[i] = atoi(buff); doesn't seem to work. when I tried to printout the buffInt[i] in a loop, nothing happened.

    Anyone please help me.
    Thanks
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Why again don't you think that the atoi worked? When you step through your program with the debugger, what does atoi seem to do?

    You're doing nothing to output the contents of buff to see what it contains. This line was commented out, but was it your attempt to output the int values of buff?
    //printf("%s", buff);

    Rather, you would have needed to loop through buffInt printf'ing buffInt[i] using a "%d" flag.

    Your test to break out upon reaching the upper limit of buff is off by one:
    if(i>200000) break;
    buff and buffInt are declared for 200000, not for 200001. Their indices range from 0 to 199999, inclusive. You need to break if i >= 200000.

    PS
    Please present us with a complete short program that demonstrates the problem. That includes the loop that you used to try to output the values in buffInt. Be sure to post the actual code that isn't working for you.

    PPS
    Stupid question: was your outputting of buffInt something like this:
    Code:
        for (i=0; i<200000; i++)
            printf("%d\n", buffInt[i]);
    If that was the case and the file contains far fewer than 200000 values, then any meaningful values would have scrolled off.

    Try running your program from the command line and pipe the output to more, which is a utility that displays its input one screen at a time; eg:
    C: myprog | more
    To exit out of more, press the 'q' key.

    Or you could implement more in your code, displaying 20 to 24 values at a time and waiting for a keypress to proceed.
    Last edited by dwise1_aol; July 2nd, 2013 at 11:34 AM.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    14
    Rep Power
    0
    Hi,

    Thanks for the correction (i>=200000).
    Also, when I uncommented the printf("%s", buff); line it worked fine. I needed to convert the char buff to an integer buff since i have to use the integer array for a function I need to implement in the future. I also tested the buffInt[i] = atoi(buff); line but nothing happened..
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Again I request that you show us the code that you used to attempt to display the integer array, buffInt.

    How exactly did you test the atoi line? Exactly how did you determine that "nothing happened"?
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Also, you declare buff to be 200000 characters long, but you limit fgets to only reading up to 255 characters.

    Why must buff be so incredibly enormous? Why can't it just be 256 characters long?

    I'm very nervous about declaring huge arrays locally, since they go on the stack and the stack is very limited compared to static storage. I have personally blown stacks clear out of the water by declaring large local arrays.

    For example, on a 32-bit system an int is 4 bytes long (2 bytes on a 16-bit system; I don't know what yours is). 200,000 4 = 800,000 bytes, which is 0.763 MB. With buff added in, you're eating up one million bytes of the stack there, 0.95 MB. In a 16-bit system, the stack can be no larger then 64 KB -- I'm not sure what the limit is on a 32-bit system.

    I would recommend that you either move those arrays out of the function to file scope, or at the very least declare them as static so that they will be moved out of the stack into stack storage (which is where globals would go).
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Another stupid question: How do you know that you were even able to open the file?

    There is no error message when the file fails to open. As a result, judging from the code fragment that you have posted, the program would have "done nothing".
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    int main()
    {
        FILE *fp;
        char buff[200000];
        int buffInt[200000];
        int i = 0;
        int count;
    
        fp = fopen("input.txt", "r");
        if( fp == NULL )
            perror("File failed to open");
        else
        {
            while ( !feof(fp ) )
            {
                memset(buff, '\0', sizeof( buff) );
                fgets(buff, 255, (FILE*)fp);
                if(i>200000) break;
                else
                {
                    buffInt[i] = atoi(buff); //important line..
                    i++;
                }
             //printf("%s", buff);
            }
            fclose(fp);
            count = i;
            
            for (i=0; i<count; i++)
                printf("%d\n", buffInt[i]);
        }      
        
        return 0;
    }
    C:TEST>a
    39555
    76914
    62328
    96066
    78739
    31842
    83766
    18474
    86578
    78136
    71620
    61066
    63789
    2824

    C:TEST>
    Works for me. Except for saving i in count so that I can limit the number of values I display to the number that had been read in and for outputting the values in buffInt and for including the necessary standard library header files and for bringing the open braces out of hiding, that is your code I'm using, copy-and-pasted directly from your OP.

    Why doesn't it work for you? What are you doing differently? Please show us.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    14
    Rep Power
    0
    Hi guys,

    Sorry, I was not on my desktop for a while. I have a .txt file with 50,000 elements in this order:
    39555
    76914
    62328
    96066
    78739
    31842
    83766
    18474
    86578
    78136
    71620
    61066
    63789
    ......
    kth term.

    So, like the code shows, I copied it into a char buffer . The 256 works fine. Infact, when I printf("%s", buff), the whole 50,000 elements where displayed. So, there is no problem with the char buff. The problem is with the int bufferInt. Let's just for experiment purpose reduce the array size from 200,000 to 50,000. I want to convert each character that to int . That is. in buff[0] = '"39555" to buffInt[0] = 39555;
    and I want to do this for buff[0] to buff[k-1] where k the size of the buff character array. That is what I intend to achieve.
    Now, i suspect the line buffInt[i] = atoi(buff) might be wrong as that seems to want to take everything in buff i.e 0...k-1 and push them in just the ith element of buffInt continuously. Hope someone understands what I aim to achieve?
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    14
    Rep Power
    0
    Originally Posted by dwise1_aol
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    int main()
    {
        FILE *fp;
        char buff[200000];
        int buffInt[200000];
        int i = 0;
        int count;
    
        fp = fopen("input.txt", "r");
        if( fp == NULL )
            perror("File failed to open");
        else
        {
            while ( !feof(fp ) )
            {
                memset(buff, '\0', sizeof( buff) );
                fgets(buff, 255, (FILE*)fp);
                if(i>200000) break;
                else
                {
                    buffInt[i] = atoi(buff); //important line..
                    i++;
                }
             //printf("%s", buff);
            }
            fclose(fp);
            count = i;
            
            for (i=0; i<count; i++)
                printf("%d\n", buffInt[i]);
        }      
        
        return 0;
    }
    Works for me. Except for saving i in count so that I can limit the number of values I display to the number that had been read in and for outputting the values in buffInt and for including the necessary standard library header files and for bringing the open braces out of hiding, that is your code I'm using, copy-and-pasted directly from your OP.

    Why doesn't it work for you? What are you doing differently? Please show us.

    Hi, if you use this code, it doesn't copy the over 50,000 elements into the buffInt array.
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally Posted by help_desk
    Hi, if you use this code, it doesn't copy the over 50,000 elements into the buffInt array.
    Why not? If input.txt contains 50,000 numbers, each on its own separate line at the end of which is a '\n' (AKA "CRLF", or just a LF if on UNIX/Linux), then why would it not read in and convert each and every one of those 50,000 numbers?

    What are you doing differently that you are not telling us?

    Originally Posted by help_desk
    and I want to do this for buff[0] to buff[k-1] where k the size of the buff character array. That is what I intend to achieve.
    Now, i suspect the line buffInt[i] = atoi(buff) might be wrong as that seems to want to take everything in buff i.e 0...k-1 and push them in just the ith element of buffInt continuously. Hope someone understands what I aim to achieve?
    At any given time that atoi(buff) is called, buff just contains the line from the text file that contains the next individual number; eg "39555\n". That is everything that is in buff! Your own code ensures that that is everything that is in buff. But it looks like you are saying that there is more in buff besides that. What else is there? What else could there possibly be?

    I do not understand your problem, because it doesn't make any sense, especially in light of your own code. Please provide us with a specific case detailing what the data is going in and its exact format, and the results that you get.

    And, yet again, a complete code listing that we can ourselves compile and test.

    And I still do not know exactly how you had tested the return value of atoi(buff).
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    14
    Rep Power
    0
    Originally Posted by dwise1_aol
    Why not? If input.txt contains 50,000 numbers, each on its own separate line at the end of which is a '\n' (AKA "CRLF", or just a LF if on UNIX/Linux), then why would it not read in and convert each and every one of those 50,000 numbers?

    What are you doing differently that you are not telling us?


    At any given time that atoi(buff) is called, buff just contains the line from the text file that contains the next individual number; eg "39555\n". That is everything that is in buff! Your own code ensures that that is everything that is in buff. But it looks like you are saying that there is more in buff besides that. What else is there? What else could there possibly be?

    I do not understand your problem, because it doesn't make any sense, especially in light of your own code. Please provide us with a specific case detailing what the data is going in and its exact format, and the results that you get.

    And, yet again, a complete code listing that we can ourselves compile and test.

    And I still do not know exactly how you had tested the return value of atoi(buff).
    Hi, buff's length is the length of elements in the .txt file I copied from. each element of buff contains an array of characters..so, buff[0] = "399567" , buff[1] = "399568" , buff[2] = "399547" ..... up till buff[50,000] = "432111".. Now, I want to convert each to an integer buffInt array as this :
    buffInt[0] = 399567 , buffInt[1] = 399568 , buffInt[2] = 399547....up till buffInt[50,000] = 432111. That is just the summary of what I want to do.
  22. #12
  23. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    > Hi, buff's length is the length of elements in the .txt file I copied from.
    But you're reading the file one line at a time.

    > each element of buff contains an array of characters.
    No it doesn't. Each element of buff is a single character, not a string.

    So after the first fgets call, it would be something like
    buff[0] = '3';
    buff[1] = '9';
    buff[2] = '9';
    buff[3] = '5';
    buff[4] = '6';
    buff[5] = '7';
    buff[6] = '\n';
    buff[7] = '\0';

    In other words, buff = "399567\n\0"

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    int main()
    {
        FILE *fp;
        char buff[255];  // You're not storing the whole file, just one line at a time
        int buffInt[200000];
        int i = 0;
        int count;
    
        fp = fopen("input.txt", "r");
        if( fp == NULL )
            perror("File failed to open");
        else
        {
            while ( i < 200000 && fgets(buff, 255, fp) != NULL )
            {
    //!! waste of effort, remove it            memset(buff, '\0', sizeof( buff) );
    //!! why the cast of fp???            fgets(buff, 255, (FILE*)fp);
    //!! test moved to while loop            if(i>200000) break;
    //!!            else
    //!!            {
                    buffInt[i] = atoi(buff); //important line..
                    i++;
    //!!            }
             //printf("%s", buff);
            }
            fclose(fp);
            count = i;
            
            for (i=0; i<count; i++)
                printf("%d\n", buffInt[i]);
        }      
        
        return 0;
    }
    I suggest you try this with a cut-down input.txt containing say just 10 numbers, then post a screen-shot of what you actually see (assuming it's still failing for you).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  24. #13
  25. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    You still have answered none of the questions that I raised, nor have you provided us with a small complete program that demonstrates your problem. We need a complete program so that we can compile it. And it needs to demonstrate your problem so that we can see why it's doing that.

    Now, again, why did you claim: "if you use this code, it doesn't copy the over 50,000 elements into the buffInt array." ? That claim makes absolutely no sense whatsoever.

    Again, what are you doing differently? Your original code works, so why are you having problems? Maybe it's something in another part of your program, so show us the rest of your program! We're not mind-readers!

    Originally Posted by help_desk
    Hi, buff's length is the length of elements in the .txt file I copied from. each element of buff contains an array of characters..so, buff[0] = "399567" , buff[1] = "399568" , buff[2] = "399547" ..... up till buff[50,000] = "432111".. Now, I want to convert each to an integer buffInt array as this :
    buffInt[0] = 399567 , buffInt[1] = 399568 , buffInt[2] = 399547....up till buffInt[50,000] = 432111. That is just the summary of what I want to do.
    OK, we already knew that. Though, BTW, you're talking about reading in 50,001 numbers, not 50,000; keep array indexing straight in your mind at all times.

    That is what your original code does, once I embedded it into a complete program. If your own complete program does not do that, then show us your own complete program! All we have to go by is what you tell us and what you're telling us does not make any sense!

    We already know what you are trying to do, so stop trying to explain that to us. Instead, tell us what your program is actually doing! You're not getting the results that you expect? So tell us precisely what those unexpected results are!

    Also, tell us precisely what the format of your input.txt file is. This is what we would expect it to be:
    1. It consists of several individual lines of text, each one ending with a newline. In Windows/DOS text files, a newline is a two-character sequence, carriage return-line feed, AKA "CRLF". In UNIX/Linux, a newline is one character, a line feed -- the system fills in the CR. Both possible newline sequences are represented in C by '\n', though some protocols such as HTTP would require and explicit "\r\n".

    fgets reads in one complete line up to and including the newline.

    2. Each line in input.txt contains a character string representing one and only one integer number. This means that if you have 50,001 numbers to read in, the text file will contain 50,001 individual lines.

    Is that the format of your input file, input.txt?

    Remember, we cannot read your mind, so you need to provide us with the information that we need as we request it.

IMN logo majestic logo threadwatch logo seochat tools logo