Thread: Reading to the end of the file

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    3

    Reading to the end of the file

    hey, I was wondering if i could get some help. I have this so far. I don't want to use an array or vector.


    Code:
    #include <fstream>
    #include <cstdlib>
    
    using namespace std;
    
    int main()
    {
    	string boy, girl, name, next;
    	char symbol;
    	ifstream infile;
    	int rank;
    	
    	infile.open("babynames2004.txt");
    	if(infile.fail()){
    		cout << "Error: File opening failed." << endl;
    		exit(1);
    	}
    	
    
    	infile >> rank >> boy >> girl >> symbol;
    	//is there any way to loop this so it goes all the way to the end of the file?
    	
    	
    	cout << "Enter a name to see how popular it is." << endl
    		 << "Please capitalize the name." << endl;
    	cin >> name;
    
    	if ( name == boy){
    		cout << name << " is ranked " << rank << " in popularity among boys." << endl;
    	}
    	else if (name == girl){
    		 cout << girl << " is ranked " << rank << " in popularity among girls." << endl;
    		 }
    		 else{
    		 cout << name << " is not ranked among the top 1000 boy or girl names." << endl;
    		 }
    	
    	infile.close();
    	
    return 0;
    }

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    First, welcome to the board. Please don't bump old threads. Create a new thread and if there is something in that thread you want to refer to, just provide a link. I'm sure a moderator will split your question off into its own thread soon enough so...

    >> I don't want to use an array or vector.
    If you don't want to use an array or vector or some other container, then that means you have to read through the entire file every time you look up a name. That's not the most efficient way to do it, but it can be done.

    >> is there any way to loop this so it goes all the way to the end of the file?
    Yes. Put it in a while loop.

    The return value of that specific line will be true if it properly read in some data, so use that to control your loop:
    Code:
    while (infile >> rank >> boy >> girl >> symbol)
    {
        ...
    }
    Now see if you can figure out which code goes inside that loop. You'll have to re-arrange your other code as well, but I'll leave that work up to you.

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    28
    Heres how i would do it. Use this as an example but this makes the most sense for me. You can probably do it a few other ways too.

    Code:
    #include <cstdlib>  
    #include <fstream> 
    #include <iostream>
    #include <string>  
    #include <sstream> 
    
    using namespace std;
    
    struct NamesRank
    {
    	string rank;
        string boysName;
        string girlsName; 
        NamesRank *link;
    };
    
    typedef NamesRank* NamesRankPtr;
    
    int main()
    {
    	NamesRankPtr headOfList = NULL; //Points to head of list
    	NamesRankPtr tempPtr = NULL; 
        
    	ifstream nameIn; //Creates stream object
       
        nameIn.open( "babynames2004.txt" ); //Opens file stream
       
        if ( nameIn.fail() ) //Error handling for file stream
        {
    	    cout << "Opening of input file failed.\n";
    	    exit(1);
        }
    	
    	string tempRank;
    	string tempBoy;
    	string tempGirl;
    
        bool firstNode = true; 
        while ( !nameIn.eof() )
        {
    		if (firstNode)
    		{
    			headOfList = new NamesRank; //Creates first node
    
    			nameIn >> tempRank;
    			nameIn >> tempBoy;
    			nameIn >> tempGirl;
    	
    			headOfList -> rank = tempRank;
    			headOfList -> boysName = tempBoy;
    			headOfList -> girlsName = tempGirl;
    			headOfList -> link = NULL; // 1st node is also last node so NULL
    
    			firstNode = false; // First node created so no need to do it again
    		}
    		else
    		{
    			tempPtr = headOfList;
    			headOfList = new NamesRank; //Creates first node
    
    			nameIn >> tempRank;
    			nameIn >> tempBoy;
    			nameIn >> tempGirl;
    
    			headOfList -> rank = tempRank;
    			headOfList -> boysName = tempBoy;
    			headOfList -> girlsName = tempGirl;
    			headOfList -> link = tempPtr; 
    		}
    	}
    	nameIn.close(); // close input file
    
    	bool terminate = false;
    	while (!terminate)
    	{
    		cout << "Please enter a name or -1 to terminate\nName: ";
    		string target;
    		cin  >> target;
    		
    		tempPtr = headOfList;
    
    		while ((tempPtr->boysName != target) && (tempPtr->girlsName != target) &&
    			(tempPtr->link != NULL))
    		{
    			tempPtr = tempPtr->link;
    		}
    		
    		if (target == "-1")
    			terminate = true;
    		else if (tempPtr->boysName == target)
    			cout << target << " is ranked " << tempPtr->rank << " among boys' names.\n" << endl;
    		else if (tempPtr->girlsName == target)
    			cout << target << " is ranked " << tempPtr->rank << " among girls' names.\n" << endl;
    		else
    			cout << "baby name not found in databaase\n" << endl;
    	}        
    	system("Pause");
    	return 0;                             
    }

  4. #4
    Registered User
    Join Date
    Aug 2009
    Posts
    3
    This is where i got. I am having trouble nesting the loops. Any suggestions?
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <cstdlib>
    
    using namespace std;
    
    int main()
    {
    	string boy, girl, name, next;
    	char symbol;
    	ifstream infile;
    	int rank;
    	
    	infile.open("babynames2004.txt");
    	if(infile.fail()){
    		cout << "Error: File opening failed." << endl;
    		exit(1);
    	}
    	
    	cout << "Enter a name to see how popular it is." << endl
    		 << "Please capitalize the name." << endl;
    	cin >> name;
    	
    	while(!infile.eof()){
    	infile >> rank >> boy >> girl;
    		if(name == boy){
    		cout << boy << " is ranked " << rank << " in popularity among boys." << endl; 
    		if(name == girl){
    			cout << girl << " is ranked " << rank << " in popularity among boys." << endl;
    		}else
    			cout << name << " is not ranked among the top 1000 boy or girl names." << endl;
    		}	
    	}
    	
    	infile.close();
    	
    return 0;
    }

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by kordric View Post
    typedef NamesRank* NamesRankPtr;
    Why the heck do you use a typedef for the pointer? It does nothing more than obfuscate the code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Heres how i would do it. Use this as an example but this makes the most sense for me.
    That's fine, but there's a lot of things in there that I wouldn't consider best practice. I think it might make more sense for tiffer89 to try his or her own method and just provide hints along with that. Then, when he or she is done, you can suggest your method so tiffer89 can see another way and we can give you pointers on how to improve your code without derailing the thread.

    >> This is where i got. I am having trouble nesting the loops. Any suggestions?
    Sure.

    First, I don't think you need to nest loops. Why do you think you need to? The only reason I can see to nest loops (put one inside the other) is if you want to ask the user the question multiple times. Personally, I would get this working with just one time first.

    >> while(!infile.eof()){
    Second, this is a bad idea. eof() doesn't return true until after you have attempted a read that failed due to the end of the file, so your loop will run one extra time. I'd suggest using what I suggested previously.

    Third, you need some way to break out of your loop when you find the name. One way is to use break;, another way is to keep a variable that is set to true when you find it. Your last else is something that you probably only want to display if you finish the loop without finding the name, right?

    If you have some other rules in the assignment you have to work with, then this advice might change, but for now I hope that helps.

  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    3
    ok, I think I almost have it. but i have the loops nested wrong. when i do a name that is ranked in both boy and girl, this is the output:
    Jaime is ranked 272 in popularity among boys.
    Jaime is not ranked among the top 1000 girl names. <--i need to get rid of this
    Jaime is not ranked among the top 1000 boy names. <--i need to get rid of this
    Jaime is ranked 945 in popularity among girls.

    also, should i just make another if statement for when the name isnt in either list?

    Code:
    int main()
    {
    	string boy, girl, name, next;
    	ifstream infile;
    	int rank;
    	
    	cout << "Enter a name to see how popular it is." << endl
    		 << "Please capitalize the name." << endl;
    	cin >> name;
    	
    		infile.open("babynames2004.txt"); 
    	if(infile.fail()){
    		cout << "Error: File opening failed." << endl;
    		exit(1);
    	}
        
    	while(!infile.eof()){
    	infile >> rank >> boy >> girl;
    	  if(name == boy || name == girl){
    		if(name == boy){
    		  cout << boy << " is ranked " << rank << " in popularity among boys." << endl; 
    		}else if(name != boy)
    			    cout << name << " is not ranked among the top 1000 boy names.\n";
    					if(name == girl){
    						cout << girl << " is ranked " << rank << " in popularity among girls." << endl;		
    					}else if(name != girl)
    						  cout << name << " is not ranked among the top 1000 girl names.\n";
    	  }
    	}
    	infile.close();
    return 0;
    }

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    When do you know for sure that the name isn't in the top 1000? Is it somewhere inside the loop while you're still looking, or is it after you've finished checking them all? You still need a variable to remember whether you've found the name or not (or maybe two, one for boys and one for girls).

    BTW, did you ignore my suggestion about not using while(!infile.eof()) on purpose? I honestly don't mind if you don't take my advice, I just want to make sure you're doing it on purpose.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 13
    Last Post: 05-31-2009, 11:30 AM
  2. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  3. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  4. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM