fread not playing nice; my array is full of zeros

This is a discussion on fread not playing nice; my array is full of zeros within the C Programming forums, part of the General Programming Boards category; I'm sure it's my lack of coding skills, not fread's fault : ). I'm trying to read a text file ...

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    7

    fread not playing nice; my array is full of zeros

    I'm sure it's my lack of coding skills, not fread's fault : ).

    I'm trying to read a text file full of integers into an array. The input file consists of one integer per line and the number of lines will be dynamic in the program.

    Input example:
    1
    2
    3
    etc...

    Code:
    long lSize;
    char filename[25];
    char temp[50];
    FILE *pfile;
    int elements;
    int *realdata;
    int count;
    
    //get file name, open file
    printf("\n\n\tEnter file name with path:");
    scanf("%s",filename);
    printf("\n\tFile: %s",filename);
    
    pfile = fopen (filename,"r");
    
    if (pfile==NULL) 
    {
    	perror("\tFile open error");
    	exit(EXIT_FAILURE);
    }
    else
    
    // obtain file size:
    fseek (pfile , 0 , SEEK_END);
    lSize = ftell (pfile);
    rewind (pfile);
    
    printf("\n\tFile size: %ld bytes",lSize);
    
    //count lines for dynamic allocation of array
    while ( fgets ( temp, sizeof temp, pfile) != NULL )
    {
    	elements++;
    }
    
    printf("\n\tNumber of elements: %d",elements);
    printf("\n\tElement size: %ld\n\n",sizeof(int));
    
    //dynamic allocation of array for real data
    realdata=calloc(elements, sizeof(int));
    if (realdata == NULL) 
    {
    	perror("\tReal Data array allocation error");
    	exit(EXIT_FAILURE);
    } 
    else 
    
    //read file data to real data array
    if (fread (realdata,sizeof(int),(size_t)elements,pfile)!=elements)
    {
    	fprintf(stderr, "\terror reading file\n\n"); 
    	exit(1);
    }
    fclose(pfile);
    
    //print real data array
    for (count = 0; count < elements; count++)
    { 
    	printf("%d", realdata[count]);
    }
    If I take out the fread error check thing (!=elements etc.) I get an array full of zeros. As it stands now, all I get is "error reading file". Any ideas are most welcome!

    As a side note why do both ubuntu and ftell claim the size of a particular txt file is 330 bytes when 4bytes/integer x 149 integers = 596 bytes. Should my array be allocated for size of integers*number of integers, or the size yielded by ftell? TIA!!
    Last edited by voraciousveggie; 03-11-2010 at 10:54 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    If it's a text file, then you cannot use it as both text, and "4bytes/integer x 149 = 596" ...

    Either you've written them as text, or you haven't.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Input example:
    1
    2
    3
    etc...
    Code:
    pfile = fopen (filename,"r");
    Code:
    if (fread (realdata,sizeof(int),(size_t)elements,pfile)!=elements)
    Your sample input file is a plain-text, ASCII file, but you then go to read it as if it were a binary file. If you use these "lower"-level functions, you should be dealing with binary data. Therefore, you should first "fwrite" these integers to the file, as binary data first. Then open the file as binary ("rb" not "r"), and then you can work with them this way.

    Also, you keep "fgets"ing until there is no more input, then you later "fread" the file, which will result in an EOF because you're already at the end of the file. You should probably "rewind" or seek back to the beginning of the file.

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    7
    Therefore, you should first "fwrite" these integers to the file, as binary data first.
    Theses numbers are not output from another program, there is no opportunity to "fwrite", I need to get them into a program first, then I can work with them.

    Ok since I'm not using binary data, I'm ditching the lower level functions. Attempting to use fscanf as follows (in place of if(fread...) section) but still getting an array full of zeros. I would be grateful for any help, again.

    Code:
    for (count = 0; count <= elements; count++) 
    {
    fscanf (pfile, "%d", realdata);
    }
    Does this contain any obvious errors to anyone?

  5. #5
    a_capitalist_story
    Join Date
    Dec 2007
    Posts
    2,648
    Code:
    for (count = 0; count <= elements; count++)
    That's an array overrun.

    Code:
    fscanf (pfile, "%d", realdata);
    Wouldn't you prefer to read into the individual array elements?

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    7
    That's an array overrun.
    Doesn't it loop exactly as many times as there are elements?

    Wouldn't you prefer to read into the individual array elements?
    I'll try anything that works, are you talking about fgets? Doesn't that read into a string that needs to be converted to integers with atoi or something? I'd like to elimintate steps if possible. I also don't want an extra "/0" as the last element of my array, if possible.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,310
    Quote Originally Posted by voraciousveggie
    Doesn't it loop exactly as many times as there are elements?
    It loops one more time. Notice the 0 and the <=
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    7
    It loops one more time. Notice the 0 and the <=
    Right, ok that's an easy fix.

    I'm most concerned with if the method is feasible. Right now I am not getting any numbers read into the array, just a bunch of zeros when I print out. Would that be the result of an array overflow, or do I have another problem?

  9. #9
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    I'd suggest to post your complete and updated code. Without it we can only make suggestions/reasons based on assumptions we create.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by voraciousveggie View Post
    Doesn't it loop exactly as many times as there are elements?



    I'll try anything that works, are you talking about fgets? Doesn't that read into a string that needs to be converted to integers with atoi or something? I'd like to elimintate steps if possible. I also don't want an extra "/0" as the last element of my array, if possible.
    I think his point is that you read into the [0] element of the array, 1000000 times, and read into all the other elements of the array, never.

  11. #11
    Registered User
    Join Date
    Mar 2010
    Posts
    7
    Ok here's the whole shabang:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    int main()
    {
    long lSize;
    char filename[25];
    char temp[50];
    FILE *pfile;
    size_t elements;
    int count;
    int *realdata;
    
    //get file name, open file
    printf("\n\n\tEnter file name with path:");
    scanf("%s",filename);
    printf("\n\tFile: %s",filename);
    pfile = fopen (filename,"r");
    
    if (pfile==NULL) { perror("\tFile open error"); exit(EXIT_FAILURE); }
    // obtain file size: fseek (pfile , 0 , SEEK_END); lSize = ftell (pfile); rewind (pfile); printf("\n\tFile size: %ld bytes",lSize); elements=0; //count lines for dynamic allocation of array
    while (fgets ( temp, sizeof temp, pfile) != NULL ) { elements++; }
    printf("\n\tNumber of elements: %zd",elements); printf("\n\tElement size: %zd \n\n",sizeof(int)); //dynamic allocation of array for real data realdata=calloc(elements, sizeof(int));
    if (realdata == NULL) { perror("\tReal Data array allocation error"); exit(EXIT_FAILURE); }
    //read file data to real data array
    for (count = 0; count < elements; count++) { fscanf (pfile, "%d", &realdata[count]); }
    fclose(pfile); //print real data array
    for (count = 0; count < elements; count++) { printf("%d", realdata[count]); }
    printf("\n\n"); free(realdata); return 0; }
    And the output:
    Code:
    	Enter file name with path:1stnum.txt
    
    	File: 1stnum.txt
    	File size: 330 bytes
    	Number of elements: 149
    	Element size: 4 
    
    00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    I think his point is that you read into the [0] element of the array, 1000000 times, and read into all the other elements of the array, never.
    Attempted to address with the addition of realdata[count] to the read loop, which resulted in my complier complaining that realdata was no longer a pointer, but an int.
    Last edited by voraciousveggie; 03-16-2010 at 09:30 PM.

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    1. Press edit. Indent. Press save.
    2. Are you missing a pair of braces here, or did you mean for there to just be one statement executed on an else?
    Code:
    else
    
    // obtain file size:
    fseek (pfile , 0 , SEEK_END);
    All the rest is always executed. You do the same thing later on as well. We can't actually tell, because you don't have any indentation.
    3. Compile with warnings on. If you had, you'd see that this is wrong:
    Code:
    	fscanf (pfile, "%d", realdata[count]);
    You need the address of a specific variable if you are trying to scan.


    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User
    Join Date
    Mar 2010
    Posts
    7
    1. have a little indenting
    2. else's now gone
    3. compiler did complain, added & for address

    Code:
    for (count = 0; count < elements; count++) 
    {
    	fscanf (pfile, "%d", &realdata[count]);
    }
    4. Still have an array full of zeros
    .
    .
    .

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You never rewind your file after you run through it calling fgets. You're already at the end of your file. Your fscanf loop doesn't do anything. You should start checking the return values of your functions. Don't just assume everything works.


    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User
    Join Date
    Mar 2010
    Posts
    7
    wow, that was mentioned earlier and I thought "I did too rewind!" not realising I needed to rewind TWICE.

    Thank you for putting up with my ignorance, your help was awesome.

    Thanks to everyone who helped.

    Edit: check return values my children.
    Last edited by voraciousveggie; 03-16-2010 at 10:48 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. How to load pixels of BMP into an array
    By brconner in forum Windows Programming
    Replies: 10
    Last Post: 06-02-2007, 04:30 AM
  3. Having trouble printing from an array
    By Sir Andus in forum C Programming
    Replies: 2
    Last Post: 10-30-2006, 12:48 PM
  4. array full of different types
    By jmass16 in forum C Programming
    Replies: 7
    Last Post: 09-12-2006, 12:43 AM
  5. hashing help
    By alokin in forum C Programming
    Replies: 17
    Last Post: 10-28-2002, 05:33 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21