Thread: Problem reading in Text File

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    20

    Problem reading in Text File

    I am reading in a file and storing its information into this structure:

    Code:
    typedef struct Item
    {
       char *name;
       int area;
       struct Item *nextPtr;
    } Item;
    
    typedef Item *Ptr;
    The text file looks like this:
    Code:
    Bread
    0
    Toast
    1
    Butter
    0
    ...with the name of the item followed by the location of the item in integer form.


    I am getting the information from the text file into the structure like so:

    Code:
    void loadItems(Ptr *sPtr)
    {
       FILE *file;
       char stuff[30];
       char area[10];
       Ptr newPtr;
    
       if((file = fopen("items.txt", "r")) == NULL)
       {
          perror("items.txt");
          exit(1);
       }
    
       while(1)
       {
          if(fgets(stuff, 30, file) == NULL)
          {
             break;
          }
          stuff[strlen(stuff) - 1] = '\0';
    
          newPtr = malloc(sizeof(Ptr));
    
          if(newPtr != NULL)
          {
             newPtr->name = stuff;
             sscanf(area, "%d", &newPtr->area);
          }
    I didn't include all of the code in this function for simplicity's sake (please let me know if more code would be helpful.

    MY QUESTION IS...

    When reading in the file, the fgets at the beginning of the while loop still reads in the numbers, even though the sscanf at the end of while loop reads them in as well. Is there any way I can get the fgets to skip the numbers? I figured the sscanf would bump the fgets to the next word, but I guess I was wrong...hopefully that makes sense and isn't too convoluted!

  2. #2
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    A couple of problems:

    1. Do not typedef pointers, you have been told that before. It is extremely poor programming practice.
    2. You stuff array is local to your function and goes out of scope when your function exits. Thus leaving your node pointing to invalid memory.
    3. Why would sscanf effect where your file pointer was. You have it reading from your area buffer, which you never put anything into, and then outputting into your area value of your node. How does that change the file pointer? Here is sscanf explanation.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    typedef struct Item
    {
        char *name;
        int area;
        struct Item *nextPtr;
    } Item;
    
    typedef Item *Ptr;
    
    ...
    
    Ptr newPtr;
    
    ...
    
    newPtr = malloc(sizeof(Ptr));
    That certainly doesn't look right... you mean sizeof(*newPtr) instead?
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    Aug 2011
    Posts
    20
    @Andrew, the typedef pointer is actually coming straight from my textbook (C: How to Program by Deitel). While that does not make this decision any better, I am trying to follow the examples as best as possible from the book (the mistakes are all mine, though, haha). I am fully intent on taking your advice in the future.

    Is there any way I could replace the sscanf with an fgets, or will fgets not be able to store the number into an integer variable? Is there any way I could bump the file pointer forward otherwise?

  5. #5
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Quote Originally Posted by voidpain() View Post
    Is there any way I could replace the sscanf with an fgets, or will fgets not be able to store the number into an integer variable? Is there any way I could bump the file pointer forward otherwise?
    I am not sure of your file layout, however normally you would just read the file in line by line using fgets into some buffer and then break that up with sscanf() to effectively parse the line. So something like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct myNode{
    	char name[30]; //note this isn't a pointer
    	int number;
    };
    
    //just used to make our file
    void createFile(void);
    
    int main(void){
    
    	//used for file line input
    	char inputBuffer[100]={0};
    	FILE* myFile;
    	int current=0;
    	
    	//I am using an array but this would be your linked list
    	struct myNode myNodeArray[5];
    	//---------------------
    	
    	//just makes our file to read in
    	createFile();
    	
    	//open our file
    	myFile = fopen("example.txt", "r");
    	
    	if(myFile){
    		//read our file in line by line
    		while(fgets(inputBuffer, sizeof(inputBuffer), myFile) && current < 5){
    			//break up our line into our structure
    			sscanf(inputBuffer,"%s %d", myNodeArray[current].name, &myNodeArray[current].number);
    			current++;
    		}
    		fclose(myFile);
    	}
    	//printf our results
    	for(int i = 0; i < current; i++){
    		printf("%s %d\n", myNodeArray[i].name , myNodeArray[i].number);
    	}
    
    	getchar();
    	return (0);
    }
    void createFile(){
    
    	FILE* myfile = fopen("example.txt", "w");
    	if(myfile){
    		fprintf(myfile, "John 30\n");
    		fprintf(myfile, "Joe 20\n");
    		fprintf(myfile, "Bob 15\n");
    		fclose(myfile);
    	}
    }
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by voidpain() View Post
    Is there any way I could replace the sscanf with an fgets, or will fgets not be able to store the number into an integer variable? Is there any way I could bump the file pointer forward otherwise?
    Maybe you would find fscanf() more useful.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Aug 2011
    Posts
    20
    Awesome, fscanf() worked nicely, thanks!

    Thanks Andrew, I'm trying the things in your code in a different file right now

  8. #8
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Also, I would like to note that unless there is any reason your files need to be human readable, e.g. txt files, you really should look at just making binary files for this. I am assuming you are making something of a game here, so in that case it would greatly simplify how you manages these files and load your data.

    Just search this forum and the internet for "Random Access Files". By doing this you will have many advantages such as reading and writing directly from/to a structure and being able to jump around in your data file, hence "random access".
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 05-05-2010, 02:43 PM
  2. Reading Text File (spaces problem)
    By kekewong in forum C Programming
    Replies: 1
    Last Post: 04-15-2009, 03:34 PM
  3. problem reading a text file.
    By jerrykelleyjr in forum C Programming
    Replies: 13
    Last Post: 10-25-2006, 06:18 AM
  4. Reading text file twice, can it be done once?
    By CaeZaR in forum C Programming
    Replies: 2
    Last Post: 02-03-2006, 03:34 PM
  5. reading from text file
    By david999 in forum C Programming
    Replies: 8
    Last Post: 11-04-2005, 05:14 PM

Tags for this Thread