Thread: Reading from a file

  1. #1
    Registered User *pointer's Avatar
    Join Date
    Oct 2001
    Posts
    74

    Reading from a file

    This is a school assignment that I got today and I can't figure out why I get messed up output. The file is supposed to have one line with several numbers and words that are to be put into separate variables, the last number in that line will determine how many more lines to input before beginning again. This is done until the end of the file is reached.

    So if the first line is
    10428 Davis Richard Mahomet iL 64855 1
    then the program should read one line after that before moving on to the next element in the structure array.
    If the first line is
    10186 Allan James Gainseville WA 21813 4
    then the program will read four lines before going to the next element in the structure array.

    In the process of debugging, I found that when I create a new data file with only the first lines instead of everything, the program will read them fine. But when I add the other lines I get messed up output.

    Here's the source code, let me know if anyone wants the datafile as well to see what I mean.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAXNUMBER 5
    #define LINELENGTH 26
    
    typedef struct {
      long int number1;
      char string1[16];
      char string2[16];
      char string3[16];
      char string4[3];
      char line1[26];
      char line2[26];
      char line3[26];
      char line4[26];
      long int number2;
      int number3;
    } INPUT;
    
    int main( void ) {
      int i = 0, j = 0;
      FILE *INSTREAM;
      INPUT data[5];
    
      if ( ( INSTREAM = fopen("a:\\datafile.txt", "r") ) == NULL ) {
        printf("Could not open file!");
    	exit(1);
      }
    
      while( i < MAXNUMBER ) {
    	for ( j = 0; j < MAXNUMBER; j++ ) {
    	  data[i].string1[j] = '\0';
    	  data[i].string2[j] = '\0';
    	  data[i].string3[j] = '\0';
    	}
    	fscanf( INSTREAM, "%ld %s %s %s %s %ld %d", &data[i].number1, &data[i].string1,
    	  &data[i].string2, &data[i].string3, &data[i].string4, &data[i].number2, &data[i].number3 );
    
            fgets( data[i].line1, 26, INSTREAM );
            if( data[i].number3 > 1 )
                fgets( data[i].line2, 26, INSTREAM );
            if( data[i].number3 > 2 )
                fgets( data[i].line3, 26, INSTREAM );
            if( data[i].number3 > 3 )
                fgets( data[i].line4, 26, INSTREAM );
    
            /*for ( j = 0; j < LINELENGTH; j++ )
                fscanf( INSTREAM, "%c", data[i].line1 );
            for ( j = 0; j < LINELENGTH; j++ ) {
                if( data[i].number3 > 1 )
    	        fscanf( INSTREAM, "%c", data[i].line2 );
            }
            for ( j = 0; j < LINELENGTH; j++ ) {
                if( data[i].number3 > 1 )
                    fscanf( INSTREAM, "%c", data[i].line3 );
            }
            for ( j = 0; j < LINELENGTH; j++ ) {
                if( data[i].number3 > 1 )
    	        fscanf( INSTREAM, "%c", data[i].line4 );
            }*/
    	printf( "%ld %s %s %s %s %ld\n", data[i].number1, data[i].string1, 
    	  data[i].string2, data[i].string3, data[i].string4, data[i].number2, data[i].number3 );
    	printf( "%s\n%s\n%s\n%s\n\n", data[i].line1, data[i].line2, data[i].line3, data[i].line4 );
    	
    	i++;
      }
      return 0;
    }
    Thanks in advance.
    pointer = NULL

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I'm not sure I understand the goal of this project. What does the last number represent?

    2342 job billy bob jim 3242 4

    So 4 is what exactly? How many more of these lines I read?
    If so, what about their final number? Is it there? Is it just ignored?

    Quzah.

  3. #3
    Registered User *pointer's Avatar
    Join Date
    Oct 2001
    Posts
    74
    Okay, here's a sample of what I need to do

    /*first structure element*/
    10117 Adams Rich Champaign Il 97014 1 //read 1 line after this one
    1750 Briarwood Road

    /*second structure element*/
    10143 Alexander Nancy Bethany ma 26779 2 //read 2 lines after this one
    7452 Magnolia Drive
    Apartment #17

    /*third structure element*/
    10186 Allan James Gainseville WA 21813 4 //read 4 lines after this one
    c/o Hill Technology
    3180 Clairmont Road
    North Building
    Suite #345

    and so on...
    The first line is split up into separate variables, but subsequent lines are to be placed in one char array.
    pointer = NULL

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Ok. Now those "following lines", they are read into the same data segment as the first? Not that it really matters...
    Code:
    char buf[80];
    
    do
    {
       fgets( buf, LINE_LENGTH, fp );
       sscanf( buf, "%d %s %s %s %s %d %d", /*your vars here*/ );
    
       for( x = 0; x < data->finalValue; x++ )
       {
          fgets( data->extralines[x], LINE_LENGTH, fp );
       }
    } while( !feof( fp ) );
    Piece of cake.

    Quzah.

  5. #5
    Registered User *pointer's Avatar
    Join Date
    Oct 2001
    Posts
    74
    No, if anything that made it worse. Perhaps you should run the program with the data file and see what I mean about funny output.
    pointer = NULL

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Um... it works fine. I'm not going to do all of your homework, but this is what I did, and it works fine with your data file:
    Code:
    struct mydata {
    	int number;
    	char	s1[LINE_LENGTH],
    			s2[LINE_LENGTH],
    			s3[LINE_LENGTH],
    			s4[LINE_LENGTH];
    	int number2;
    	int finalValue;
    	char extralines[10][80];
    };
    Now, notice that I am assuming you're only ever going to have that last digit never more than 10. You could allocate the number you need, but I took the short way out.

    Ah screw it. It does work. This is what I did:

    Code:
    	for( y=0; y<10; y++ )
    	{
    	/*
    		I am assuming only 10 "entries"
    		in this file. Where an "entry" is
    		the original line with the "finalnumber".
    
    		The additional lines are "subentries".
    	*/
    		fgets( buf, LINE_LENGTH, fp );
    		puts( buf );
    		sscanf( buf, "%d %s %s %s %s %d %d",
    			/*
    				Variables go here.
    				Make sure you are
    				using sscanf() right.
    			*/
    		);
    
    		for( x = 0; x < array[y].finalValue; x++ )
    		{
    			fgets( array[y].extralines[x], LINE_LENGTH, fp );
    			if( feof( fp ) ) break;
    		}
    		if( feof( fp ) ) break;
    	}
    Just like I said. The only thing different is that you (and I, since I wasn't paying attention, still, you should have caught that ) need to loop through and tell it to put the stuff in the right spot. (Notice my addition of the Y counter.

    Quzah.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM