Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Reading .txt files to an array in C language

  1. Jun 23, 2012 #1
    I have a .txt file with 100,000 integers from 1-100,000, with each integer in a newline. I am facing a problem in using the fgets function. How do I read the integers into an array?


    Code (Text):
    #include <stdio.h>

    //Program to count number of inversions in an input file of integers using Brute force method

    main()
    {
    int i,j,k=0;
    FILE *f;
    int a[100000];
    char *buffer;
    f=fopen("IntegerArray.txt","r");
    fgets(buffer,100000,f);
    for(i=0;i!=EOF;i++)
       {
       for(j=1;j!=EOF;j++)
       {
       if(a[i]>a[j])
       k++;
       }
       }
       printf("%d",k);
    }
     
  2. jcsd
  3. Jun 23, 2012 #2
    How are the integers stored in your file? Each one on a newline?

    fgets() reads, at most your 10000 bytes, or until it hits a newline '\n' or EOF - you might want to call it in a loop if each number is on a newline in your file.

    Also, your integer array should store integers and your fgets() is reading a string, so you need to convert the characters that represent your integer in the text file, to an integer data type (lookup the atoi() function).

    What I'm thinking is something like this - you might need to play around with it.

    Code (Text):

    char *buffer;
    int BUF_SIZ = 10; // size of a line in your file, 10 digits enough for your ints?
    int array[10000];
    int i = 0;
    while(fgets(buffer, BUF_SIZ, file) != EOF && i < 10000) // while file not EOF and i is less than max array bound
    {
      int number = atoi(buffer); // convert the number you just read from string to int
      array[i] = number; // store the number in the next free array slot
      i++; // increment the array index
    }
    If you store your numbers in binary, you could use fread() to read the whole file into an int array, but I think you are storing them as ASCII text (ie. readable).
     
  4. Jun 23, 2012 #3

    jtbell

    User Avatar

    Staff: Mentor

    Surely it would be easier to read the file using fscanf() which does the character-to-integer conversion for you, with a suitable format descriptor.
     
  5. Jun 23, 2012 #4
    Code (Text):
    #include <stdio.h>
    #include <stdlib.h>

    main()
    {
    int i,j,k=0;
    FILE *f;
    int a[100000];
    char *buffer;
    f=fopen("IntegerArray.txt","r");
    while(fgets(buffer,10,f)!=EOF && i<10000)
    {  int number=atoi(buffer);
       a[i]=number;
       i++;
    }
    for(i=0;i<10000;i++)
       {
       for(j=1;j<=10000;j++)
       {
       if(a[i]>a[j])
       k++;
       }
       }
       printf("%d",k);
    }
    This code gives segmentation fault in Ubuntu (with different file location of course) and "ISO C++ forbids comparison between pointer and integer" in C free 5 pro.

    In that case too I have to use a loop, isn't it?
    Code (Text):

    int buffer,i;
    f=fopen("IntegerArray.txt","r");
    while(fscanf(f,"%d",&buffer)!=EOF)
    {i=0;
    a[i]=buffer;
    i++;
    }
    I have trouble with arguments of fscanf() function.
    Is this correct?
     
  6. Jun 23, 2012 #5

    Mark44

    Staff: Mentor

    No. Each iteration through the loop you reset i = 0, store the read value into a[0], and then increment i. In the next iteration (assuming EOF hasn't been reached), i is again set to 0, the new value of buffer is stored at a[0], overwriting the previously stored value, and then i is incremented again. There's an obvious fix for this.
     
  7. Jun 23, 2012 #6
    Sorry that was a typo. i should be initialised to 0 outside the loop.

    Code (Text):

    int i=0;
    while(fscanf(f,"%d",&buffer)!=EOF)
    {
    a[i]=buffer;
    i++;
    }
    But this does not work. The following code gives 0 as the output.

    Code (Text):
    #include <stdio.h>
    #include <stdlib.h>

    main()
    {
    int i=0,j,k=0;
    FILE *f;
    int a[100000];
    int buffer;
    f=fopen("IntegerArray.txt","r");
    while(fscanf(f,"%d",&buffer)!=EOF)
    {
    a[i]=buffer;
    i++;
    }
    for(i=0;i<10000;i++)
       {
       for(j=1;j<=10000;j++)
       {
       if(a[i]>a[j])
       k++;
       }
       }
       printf("%d",k);
    }
     
  8. Jun 23, 2012 #7

    jtbell

    User Avatar

    Staff: Mentor

    Have you tried inserting printf()'s into your code to display the values of variables while the program is running? For example, in your while-loop, display on each iteration a message like

    buffer = 12345 i = 1

    If the results look OK, do something similar in your nested for-loops.

    Run this on a smaller version of your input file (maybe ten integers) so you don't get overwhelmed with > 100,000 lines of output.

    Or you can learn how to use a debugger which lets you step through the program and examine variables. But I usually use the "extra printf()'s" method. Believe me, it's a very common technique.
     
  9. Jun 23, 2012 #8

    Mark44

    Staff: Mentor

    In the code you show in post #6, if the data in the file happens to be in sorted order, from small to large, the final value of k will be 0.

    For example, suppose the numbers in a much smaller version of your file are 1, 2, 3, 4, 5, and 6.

    The outer loop first looks at a[0] (== 1) and compares it to the subsequent values in the array, all of which are larger, so the comparison a > a[j] will be false. This means that k does not get incremented.

    The outer loop then looks at a[1] (== 2) can compares it to subsequent values in the array, so again, the comparison a > a[j] will be false, and k does not get incremented.

    The same thing keeps happening for this scenario, resulting in a value of k that is still 0.
     
  10. Jun 25, 2012 #9
    This code is working fine for smaller number of integers (I tried till 10).
    But it gives a negative answer for my input array (unsorted) of 100,000 integers. What can be the problem?

    Code (Text):

    #include <stdio.h>

    main()
    {
    int i=0,j=0,k=0;
    FILE *f;
    int a[100000];
    int buffer;
    f=fopen("C:\\Users\\Abdul Quadeer\\Desktop\\IntegerArray.txt","r");
    if(f==NULL)
    printf("File cannot be opened");
    while(fscanf(f,"%d",&buffer)!=EOF)
    {
       a[i]=buffer;
       i++;
    }
    for(i=0;i<99999;i++)
       {
       for(j=i+1;j<100000;j++)
       {
       if(a[i]>a[j])
       k++;
       }
       }
      printf("\nNumber of inversions are %d\n",k);
    }
     
  11. Jun 25, 2012 #10

    Mark44

    Staff: Mentor

    If your compiler stores ints in 16 bits, your limit of 100,000 is larger than can be stored in an int. The largest signed 16 bit value is 32,767. The largest unsigned int is 65, 535.

    Does the problem go away if you use long as the data type instead of int? You'll need to change the format specifies in your fscanf and printf statements to "%ld" instead of "%d".
     
  12. Jun 25, 2012 #11
    I had to change the data type to long long int for k variable. It's giving the correct answer now. Thank you all!
     
  13. Jun 25, 2012 #12

    Mark44

    Staff: Mentor

    You don't need long long int (64 bits). For 100,000 numbers long int (most likely 32 bits) is more than sufficient, since it can deal with numbers up to around 2,000,000,000+ (signed) or 4,000,000,000+ (unsigned).

    Your compiler must be pretty old - about 1996, many compilers switched the size of an int from 16 bits to 32 bits. Prior to that change, short int and int were 16 bits and long int was 32 bits. After the change, short int was still 16 bits, but int and long int were the same at 32 bits.
     
    Last edited: Jun 25, 2012
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Reading .txt files to an array in C language
Loading...