Thread: Read problems

  1. #1
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589

    Question ifstream read issues

    I'm having troubles getting the read to work.

    I feel this should work.

    It doesn't get past the anoted location below.

    [Edit]
    What I'm trying to do is read into my linked list.
    I used the regular ifstream, but it doesn't work.
    It isn't geting past the while loop. As if the condition never is proven true.
    [/Edit]
    Code:
    void linklist::read()              
    {
    	initializeData();
    
    	ifstream instream("members.dat",ios::in);
    
    	if (!instream)
    		cout << "File could not be opened\n....";
    	else
    	{
    		link *current;
    		
    		current = head;
    
    		while (current != tail)  //******Doesn't get  past here.
    		{cout<<"test";instream >> buffer1;
    		cout<<buffer1;
    			for(x=0;x<count1;x++)
    			{
    				
    				current->fname[x]=buffer1[x]; 
    			}
    
    			for(x=0;x<count2;x++)
    			{
    				instream >> current->lname[x];
    			}
    
    			for(x=0;x<count3;x++)
    			{
    				instream >> current->ssnumber[x];
    			}
    
    			instream>>current->age;
    			instream>>current->weight;
    
    			current = current->next;
    		}
    	}
    }
    [Edit]
    I've fix at least part of my read, but it still doesn't work correctly.
    below is the updated code. It just hangs and doesn't do anything when ran.
    [/Edit]

    Code:
    void linklist::read()              
    {
    	initializeData();
    
    	ifstream instream("members.dat",ios::in);
    
    	if (!instream)
    		cout << "File could not be opened\n....";
    	else
    	{
    		link *current;
    
    		link* newlink=new link;
    		
    		current = head;
    
    		while (!instream.eof())  //
    		{
    			instream >> buffer1[x];
    			for(x=0;x<count1;x++)
    			{
    				
    				newlink->fname[x]=buffer1[x]; 
    			}
    
    			instream>>buffer2[x];
    			for(x=0;x<count2;x++)
    			{
    				newlink->lname[x]=buffer2[x];
    			}
    
    			instream>>buffer3[x];
    			for(x=0;x<count3;x++)
    			{
    				newlink->ssnumber[x]=buffer3[x];
    			}
    
    			instream>>age;
    			newlink->age=age;
    
    			instream>>weight;
    			newlink->weight=weight;
    
    			current = newlink->next;
    		}
    	}
    }
    Last edited by xviddivxoggmp3; 10-03-2003 at 02:12 AM.
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Has your linked list already been created? If yes, and you're trying to add data into the list, then you original code is better.

    Or are you creating a new linked list? If yes, then you need to call new for each new node, then point current to the new node.

  3. #3
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589

    Question I have problems with the order of read.

    Thank you for replying I was starting to think nobody would.
    I'm trying to input a freshly read binary file into a uncreated linked list. I have it simiworking. It reads the first name, last name, and ssnumber. It doesn't read the integers weight or age that have been read. Does it need to be inputed into the file in a certain order and read in a certain order?

    Code:
     
    void linklist::read()              
    {
    	initializeData();
    
    	ifstream instream("members.dat",ios::in);
    
    	if (!instream)
    		cout << "File could not be opened\n....";
    	else
    	{
    		while (!instream.eof())  //		
                    {
    			link* newlink = new link; 
    
    			initializeData();
    
    			instream>>buffer1>>buffer2>>buffer3;
    			instream>>weight>>age;
    				
    
    			newlink->age=age;
    
    			newlink->weight=weight;
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->fname[x] = buffer1[x]; 
    			}
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->lname[x] = buffer2[x];
    			}
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->ssnumber[x] = buffer3[x];
    			}
    
    			newlink->next = head;
    
    			if (head == NULL) //this tells me I have an empty list
    			{ 
    				head = newlink;
    				tail = head;
    			}
    			else
    			{
    				head = newlink;
    			}
    		}
    	}
    	instream.close();
    }
    Last edited by xviddivxoggmp3; 10-03-2003 at 04:24 PM.
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >instream>>buffer1>>buffer2>>buffer3;
    >instream>>weight>>age;

    As long as inside the file you have a space (or newline) between ssnumber, age, and weight, this should work. You might do a cout here for age and weight to see if they're being read.
    Code:
    >for(x=0;x<SIZE;x++)
    >{
    >	newlink->fname[x] = buffer1[x]; 
    >}
    Is fname a string or char array? If char array, you could use strcpy here:
    strcpy(newline->fname,buffer1);

    Or another option is to read it directly to fname:
    instream>>newlink->fname >> newlink->lname >> newlink->ssnumber;

  5. #5
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589

    strncpy();

    I didn't think of strncpy(); that sounds a lot better.
    I tried to read directly into the the link pointer, but it didn't work.
    I have 3 char arrays (fname, lname, ssnumber) and 2 ints (age, weight). In the binary file after write it shows a blank space after the inputed data. does that mean it has a newline?
    Code:
    void linklist::write()              
    {
    	ofstream outstream("members.dat",ios::binary,ios::app);
    
    	if (isempty())
    		cout << "No nodes to write....";
    	else
    	{
    		link *current;
    		
    		current = head;
    
    		while (current != NULL)  
    		{
    			for(x=0;x<count1;x++)
    			{
    				outstream << current->fname[x]; 
    			}
    
    			for(x=0;x<count2;x++)
    			{
    				outstream << current->lname[x];
    			}
    
    			for(x=0;x<count3;x++)
    			{
    				outstream << current->ssnumber[x];
    			}
    
    			outstream<<current->age;
    			outstream<<current->weight;
    
    			current = current->next;
    		}
    	}
    	outstream.close();
    }
    Here is my write. I'm not sure if that shows what you are asking.
    But do you think strncopy(); will work on this one to? I'm unable to compile right now, so I'm not sure.

    Code:
     
    instream>>newlink->fname >> newlink->lname >> newlink->ssnumber;
    As for this, what could I be doing that would prevent this from working? I tried it in a previous build, but it didn't work.
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Is there any reason to use a binary file? Because normally when you write a binary file, you write the whole link struct in one write.

    I believe the problem is, you are not outputting a space between each item. Then when you use the >> operator to read, it looks for a space or newline between each item. To do this, you write function would look like:
    Code:
    void linklist::write()              
    {
    	ofstream outstream("members.dat",ios::app);
    
    	if (isempty())
    		cout << "No nodes to write....";
    	else
    	{
    		link *current;
    		
    		current = head;
    
    		while (current != NULL)  
    		{
    				outstream << current->fname << " "; 
    
    				outstream << current->lname << " ";
    
    				outstream << current->ssnumber << " ";
    
    			outstream<<current->age << " ";
    			outstream<<current->weight << endl;
    
    			current = current->next;
    		}
    	}
    	outstream.close();
    }
    Or you can put an endl between each item. And now you should be able to use:
    instream>>newlink->fname >> newlink->lname >> newlink->ssnumber;
    Last edited by swoopy; 10-03-2003 at 07:38 PM.

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Also, just so you know:
    > ofstream outstream("members.dat",ios::binary,ios::app);

    Use the OR operator to combine multiple ios flags:
    ofstream outstream("members.dat",ios::binary | ios::app);

  8. #8
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589

    Arrow binary file

    I was advised that I would have a lower memory overhang by using a binary file. Is this true. It was phrased to me as lower file size and less cpu usage. Is this true?
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934

    Re: binary file

    Originally posted by xviddivxoggmp3
    I was advised that I would have a lower memory overhang by using a binary file. Is this true. It was phrased to me as lower file size and less cpu usage. Is this true?
    I doubt this is true, unless you write out the whole link struct in one shot. Like this:

    outstream.write(reinterpret_cast <char *> current, sizeof(*current));

    Then to read each node from the file, use:
    outstream.read(reinterpret_cast <char *> current, sizeof(*current));

  10. #10
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589
    swoopy,

    you rock.
    it must have been other lines of faulty code when i first tried.
    below works now and I used the endl wich trimed down the file size too.
    Code:
     
    			outstream<<current->fname<<endl;
    			outstream<<current->lname<<endl;
    			outstream<<current->ssnumber<<endl;
    			outstream<<current->age<<endl;
    			outstream<<current->weight<<endl;
    [Edit]
    The below code is my working code, but I tried to rewrite the read to resemble the write to eliminate unneeded code, but it didn't work. Please compare the working with my non-working version located underneith it to see if you have any input. Thanks.
    basically what all the crap below is saying is that i'm having problems reading (instream>>newlink->fname;) It requires me to loop it and increment each individual location of the array to input the read info. Should it not allow the simple read like the write does?
    [/Edit]
    Code:
    void linklist::write()              
    {
    	ofstream outstream("members.dat",ios::binary,ios::app);
    
    	if (isempty())
    		cout << "No nodes to write....";
    	else
    	{
    		link *current;
    		
    		current = head;
    
    		while (current != NULL)  
    		{		
    			outstream<<current->fname<<endl;
    			outstream<<current->lname<<endl;
    			outstream<<current->ssnumber<<endl;
    			outstream<<current->age<<endl;
    			outstream<<current->weight<<endl;
    
    			current = current->next;
    		}
    	}
    	outstream.close();
    }
    
    void linklist::read()              
    {
    	initializeData();
    
    	ifstream instream("members.dat",ios::in);
    
    	if (!instream)
    		cout << "File could not be opened\n....";
    	else
    	{
    		while (!instream.eof())  
    		{
    			link* newlink = new link; 
    
    			initializeData();
    
    			instream>>buffer1>>buffer2>>buffer3;
    			instream>>weight>>age;
    				//;
    
    			newlink->age=age;
    
    			newlink->weight=weight;
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->fname[x] = buffer1[x]; 
    			}
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->lname[x] = buffer2[x];
    			}
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->ssnumber[x] = buffer3[x];
    			}
    
    			newlink->next = head;
    
    			if (head == NULL) //
    			{ 
    				head = newlink;
    				tail = head;
    			}
    			else
    			{
    				head = newlink;
    			}
    		}
    	}
    i tried to alter the read to clean it up like the write, but it doesn't like it at all. Se the alterations I made below.
    Code:
    void linklist::read()              
    {
    	initializeData();
    
    	ifstream instream("members.dat",ios::in);
    
    	if (!instream)
    		cout << "File could not be opened\n....";
    	else
    	{
    		while (!instream.eof()) 
    		{
    			link* newlink = new link; 
    
    			initializeData();
    
    			/*instream>>buffer1>>buffer2>>buffer3;
    			instream>>weight>>age;
    				//;
    
    			newlink->age=age;
    
    			newlink->weight=weight;*/
    
    			instream>>newlink->fname;
    			instream>>newlink->lname;
    			instream>>newlink->ssnumber;instream>>age;instream>>weight;
    			
    			
    
    			/*for(x=0;x<SIZE;x++)
    			{
    			newlink->fname[x] = buffer1[x]; 
    			}
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->lname[x] = buffer2[x];
    			}
    
    			for(x=0;x<SIZE;x++)
    			{
    			newlink->ssnumber[x] = buffer3[x];
    			}*/
    
    			newlink->next = head;
    
    			if (head == NULL) 
    			{ 
    				head = newlink;
    				tail = head;
    			}
    			else
    			{
    				head = newlink;
    			}
    		}
    	}
    	instream.close();
    }
    the out put shows garbage in the first print.
    see the output below. I want it to be more stream lined, but it looks like the only option is to go back to the working code.
    why can I not read the same as write?

    -----------------------------------------------------------------------------------
    Build and Display a linked list
    1) Add an Item to the front of the list
    2) Add an Item to the end of the list
    3) Display the list
    4) Number of nodes in the list
    5) Create an ordered list
    6) Delete a node (node n)
    7) Delete a node (by key)
    8) Destroy the list
    9) Insert a node anywhere
    10) Write to file
    11) Read file
    12) Quit this stuff
    Enter an option: 3
    The linked list looks like this so far
    Head ->

    First Name:
    ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T
    ¨T
    Last Name:
    ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T
    ¨T
    Social Security #:
    ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T¨T ¨T¨T¨T¨T¨T
    ¨T
    Age
    -12851

    Weight
    -12851

    ->
    First Name:
    john
    Last Name:
    doe
    Social Security #:
    123-12-1234
    Age
    -12851

    Weight
    -12851

    ->
    First Name:
    jane
    Last Name:
    doe
    Social Security #:
    123-65-5432
    Age
    -12851

    Weight
    -12851

    -> NULL

    Press Enter to continue....

    -----------------------------------------------------------------------------------
    Last edited by xviddivxoggmp3; 10-04-2003 at 01:14 PM.
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    xviddivxoggmp3, you're too kind .
    I'm not exactly sure what you are doing with the links in your read() function. Correct me if I'm wrong, but shouldn't head point to the first link, and tail point to the last link?

    I did some testing, and after a couple hiccups, seemingly got a read() function working. I'll post my read(). The big difference is the linked list part. Also it's missing the initializeData(), since I don't know what that does. I'll leave the cout's in there.

    One note. In my read(), I read the fname within the while. Typically if you don't do this, you'll get an extra read, because eof() doesn't become true until a read is attempted at eof. It won't hurt to leave it the way you have it for now, but something to consider if you get an extra link.
    Code:
    void linklist::read()
    {
    	char filename[] = "members.dat";
    	char firstname[30];
    	link *current;
    
    	ifstream instream(filename);
    
    	while (instream>>firstname)
    	{
    		current = new link;
    		current->next = NULL;
    
    		strcpy(current->fname,firstname);
    		instream>>current->lname;
    		instream>>current->ssnumber;
    		instream>>current->age;
    		instream>>current->weight;
    
    		cout << current->fname<<endl;
    		cout << current->lname<<endl;
    		cout << current->ssnumber<<endl;
    		cout << current->age<<endl;
    		cout << current->weight<<endl;
    
    		if (head == NULL)
    			head = current;
    		else
    			tail->next = current;
    		tail = current;
    	}
    	instream.close();
    }
    Last edited by swoopy; 10-05-2003 at 12:20 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. read only folder on Windows
    By George2 in forum Windows Programming
    Replies: 2
    Last Post: 11-05-2007, 09:18 AM
  2. read in csv file
    By gums in forum C Programming
    Replies: 5
    Last Post: 05-10-2007, 07:38 AM
  3. fread problems
    By Happy_Reaper in forum C Programming
    Replies: 4
    Last Post: 03-15-2006, 10:27 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. Replies: 1
    Last Post: 07-24-2002, 06:33 AM