Thread: For loop not running properly

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    122

    For loop not running properly

    We have project that reads a file that a user inputs and then fills an array from the inputted file and then prints out the array. I am having trouble getting this all to work with a struct, array, and for loop. It is printing two random numbers at the end and I'm not sure why. Here is the program:

    Code:
    // This program takes an array from a file and allows the user to manipulate
    // the data in the file.
    
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string>
    
    using namespace std;
    
    struct studentType
        {
            string Name;
            int ID;
            int score;
            };
    
    int main()
    { 
        int counter;
        ifstream inFile;
        string inputFile;
        
        studentType studentList[40];
        
        cout << "Enter the name of the input file: ";
        cin >> inputFile;
        
        inFile.open(inputFile.c_str());
        
        if(!inFile)
        {
             cout << "Invalid file name" << endl;
             system("pause");
             return 1;
             }
    
        inFile >> studentList[0].Name >> studentList[0].ID >> studentList[0].score;
    
        for (counter = 1; inFile; counter++)
        {
             inFile >> studentList[counter].Name
                    >> studentList[counter].ID
                    >> studentList[counter].score;
             cout << studentList[counter].Name <<  " ";
             cout << studentList[counter].ID << " ";
             cout << studentList[counter].score << " " << endl;
                }
        
         inFile.close();
         
         system("pause");
    }
    The file that is inputted is here:

    Code:
    Alex 		1220	62	
    Betsy		1121	70	
    Candace		2221	83	
    Don 		3324	90	
    Earl		4678	51	
    Francesca	5555	86	
    Guiles		6666	83	
    Henrietta	7777	73	
    Ignacius	8888	63	
    Joliet		9999	81	
    Kris		1010	66	
    Lenny		1111	76	
    Mark		1221	50	
    Noah		1331	92	
    Oscar		1441	73
    Prince		1442	75
    Queenie		7778	73
    Rob		2222	83

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You are controling your loop based on "end of file", which happens AFTER you attempt to read the last bit of your file. So you read the final line of the file, then check if you are at the end-of-file, and you are not (yet), then try to read another line of data, which fails. You still output the data you tried to (but didn't) read in - which of course is rubbish.

    You've almost got it right, because you read the first student data out before the loop starts. (but that student doesn't get output, as you may notice). You can fix both of these problems by re-arranging your existing code - just make sure you UNDERSTAND what you are re-arranging, and not just randomly re-arranging things to "hope" to get it right.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    Yes, I have noticed that the first person doesn't get outputted but I really have no idea how to go about this problem. Me and my colleague have been working at this for a few hours and have gotten no where. I am clueless.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The best way to understand what is going on is to step through the code. Either step through with a debugger (Borland, Microsoft and GNU compilers all have a debugger that can show you what is going on in the code and let you step one line at a time).

    If you don't want to use a debugger, you can also "pretend to be the computer" and "execute" one line of code at a time, just like you expect the machine to do it. Write down what the result is, taking special care about the first and last operatons in your loop.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    So what I am getting from this is that it has something to do with my inFile declarations and the for loop?

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Let's start with the printing of the first name - why is that not working?

    Stepping through the code and taking note of what happens at the first and the last steps is your key task here.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    I figured this is not working because I started off the studentType[0].Name, ID, and score with a 0 and the counter starts off at 1 but when I change the counter it does nothing.

  8. #8
    Registered User
    Join Date
    Dec 2006
    Location
    Scranton, Pa
    Posts
    252
    Your for loop isn't working like you think it should. Understand the hack below and you should be able to rewrite it to work properly.
    Code:
        //inFile >> studentList[0].Name >> studentList[0].ID >> studentList[0].score;//kill this line
    
        for (counter = 0; inFile; counter++)
        {
            while(inFile){
             inFile >> studentList[counter].Name
                    >> studentList[counter].ID
                    >> studentList[counter].score;
             cout << studentList[counter].Name <<  " ";
             cout << studentList[counter].ID << " ";
             cout << studentList[counter].score << " " << endl;
                }
               }

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    I did that but I still get the random numbers at the end.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, oldman47's solution doesn't actually solve the second part of the problem, and the solution I have in mind would actually solve BOTH problems, with less changes.

    The problem is NOT where your loop starts, but to with the order of output and input of the respective students.

    You first read student 0. Then read student 1, then print student 1, then read student 2, then print student 2, etc. etc.

    Do you see something wrong in the above statement?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    the correct format for a loop that uses feof is -

    Code:
     
    // pseudo code
     
    fread some data
    while(!feof(file) and other conditions){
       process the data
     
       fread more data
       }
    notice that the loop will terminate without executing the procesing if it does nto recieve the data.

  12. #12
    Registered User
    Join Date
    Dec 2006
    Location
    Scranton, Pa
    Posts
    252
    I didn't actually test out what I wrote earlier, though the below I did. Can't say if it's the correct approach or not, but does seem to output the correct data -
    Code:
        if(!inFile)
        {
             cout << "Invalid file name" << endl;
             system("pause");
             return 1;
             }
         
         int counter=0;
         
        while(inFile >> studentList[counter].Name
              >> studentList[counter].ID
              >> studentList[counter].score)
             {
    
             cout << studentList[counter].Name <<  " ";
             cout << studentList[counter].ID << " ";
             cout << studentList[counter].score << " "<<endl;
             
             ++counter;
            }
    
        
         inFile.close();

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    Quote Originally Posted by matsp View Post
    So, oldman47's solution doesn't actually solve the second part of the problem, and the solution I have in mind would actually solve BOTH problems, with less changes.

    The problem is NOT where your loop starts, but to with the order of output and input of the respective students.

    You first read student 0. Then read student 1, then print student 1, then read student 2, then print student 2, etc. etc.

    Do you see something wrong in the above statement?

    --
    Mats
    I see that it does not PRINT student 0, it just reads student 0. I do not see WHY this happens though

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Todd88 View Post
    I see that it does not PRINT student 0, it just reads student 0. I do not see WHY this happens though
    Where do YOU think that student 0 is printed, in your code.

    To Oldman47: Yes, that solution will work. I'd like Todd88 to work out why HIS/HER code is not working correctly - because it's a good excercise. So Todd88, assuming you are interested in learning, rather than just a quick copy'n'paste-the-correct-answer-that-someone-else-came-up-with answer, then please retain your code, and we'll work it out.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Registered User
    Join Date
    Apr 2008
    Posts
    122
    I think it is printed out at the end. That is why there are random numbers there?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 13
    Last Post: 12-09-2008, 11:09 AM
  2. Check number of times a process is running
    By linuxwolf in forum Windows Programming
    Replies: 6
    Last Post: 10-17-2008, 11:08 AM
  3. Monitor a running instance of MS Word
    By BobS0327 in forum C# Programming
    Replies: 0
    Last Post: 07-18-2008, 12:40 PM
  4. multithreading question
    By ichijoji in forum C++ Programming
    Replies: 7
    Last Post: 04-12-2005, 10:59 PM
  5. plz hlp me. program not running properly
    By jfl in forum C Programming
    Replies: 5
    Last Post: 02-11-2002, 03:58 PM