Function Help

This is a discussion on Function Help within the C++ Programming forums, part of the General Programming Boards category; My program involves taking a list of names out of a list and displaying them onto the console. A text ...

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    3

    Unhappy Function Help

    My program involves taking a list of names out of a list and displaying them onto the console. A text file located at

    C:\FinalData.txt

    The problem I'm having with one of my functions is that when it runs into a line with out of order data, it crashes. I've tried a few tricks to get it to take in the data past that line, but so far the best I've been able to do is get to quit when it runs into an error. I tried to increase my counting integer "i" when it runs into the error and tried to get it to go to the next line, but my method isn't working. How can I alter my code below so that when it runs into erronious or out of order data, it will move onto the next line.

    The problem line is number 13.

    Here is the list of names:

    000001 Moshiur Ahmed I CA 90805 40 12.50
    000002 Tasmia Amaat J CA 90706 35 25.60
    000003 Victor Barboza K CA 90706 42 30.00
    000004 Carlos Detorres I CA 90804 50 20.45
    000005 Tyree Ek O CA 90755 60 15.60
    000006 Amine El-Maziati M CA 90815 20 9.75
    000007 Loubna El-Maziati M CA 90815 25 10.50
    000008 Theresa Eyssallenne L CA 90715 40 20.00
    000009 Craig Griffith I CA 90804 40 45.00
    000010 Rodney Hallett H CA 90808 43 25.25
    000011 Andrew Hegstrom P CA 90808 45 13.50
    000012 Corey James D CA 90815 40 20.00
    000013 Farsio Kottab E 90013 CA 90755 40 20.00
    000014 Peter Lon W CA 90755 40 60.00
    000015 Joseph Lopes A CA 90808 50 100.00
    000016 Arley Lozada O CA 90280 50 30.40
    000017 Ana Moreno W CA 90805 55 14.50
    000018 Chris Myers Q CA 90802 57 30.00
    000019 Thanakom Paiboolsilp U CA 90805 56 45.75
    000020 Leonardo Priego P CA 90703 77 23.00
    __________________________________________________ __

    Here is my code:
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <conio.h>
    using namespace std;
    
    void main()
    {
    	string sEmployeeID[10000] = {""};
    	string sFirstName[300] = {""};
    	string sLastName[300] = {""};
    	string sMiddleInitial[100] = {""};
    	string sState[100] = {""};
    	int iZipCode[10000] = {0};
    	int iHours[100] = {0};
    	double dRate[1000] = {0.0};
    
    	int i = int();
    
    	ifstream finalData;
    	finalData.open("c:\\FinalData.txt");
    
    	while(!finalData.eof())
    	{
    	finalData >> sEmployeeID[i] >> sFirstName[i] >> sLastName[i] >> sMiddleInitial[i] >> sState[i] >> iZipCode[i] >> iHours[i] >> dRate[i];
    		if(finalData.fail())
    		{
    			while(!finalData.eof())
    			{
    			i++;
    			finalData >> sEmployeeID[i] >> sFirstName[i] >> sLastName[i] >> sMiddleInitial[i] >> sState[i] >> iZipCode[i] >> iHours[i] >> dRate[i];
    			}
            }
    	cout << sEmployeeID[i] << " " << sFirstName[i] << " " << sLastName[i] << " " << sMiddleInitial[i] << " " << sState[i] << " " << iZipCode[i] << " " << iHours[i] << " " << dRate[i] << " " << endl;
    	i++;
    	}
    }
    Last edited by Eradicator; 11-22-2005 at 01:19 AM. Reason: Typos

  2. #2
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    Hm...Where to start.

    Okay, first I don't know if its wrong, but I don't like the way you initialize the variable i. How about just "i = 0;". Secondly, I don't know what you think you are doing when you declare the strings. Do you really want to declare an array of 10000 string objects for employee id? I think what you want is just one string for employee id, and then you can reuse it (same for others). If I'm wrong....well then let me know. But here is your revised code if I'm right:

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <conio.h>
    using namespace std;
    
    void main()
    {
    	string sEmployeeID;
    	string sFirstName;
    	string sLastName;
    	string sMiddleInitial;
    	string sState;
    	int iZipCode;
    	int iHours;
    	double dRate;
    
    	ifstream finalData;
    	finalData.open("c:\\FinalData.txt");
    
    	while(!finalData.eof()) {
    	    finalData >> sEmployeeID >> sFirstName >> sLastName >> sMiddleInitial >> sState >> iZipCode >> iHours >> dRate;
    		if(finalData.fail()) {
                            // ignore data up to newline
                            finalData.ignore(INT_MAX,'\n');
                            // clear error flags
                            finalData.clear();
                    }
    
            }
    	cout << sEmployeeID << " " << sFirstName << " " << sLastName << " " << sMiddleInitial << " " << sState << " " << iZipCode << " " << iHours << " " << dRate << " " << endl;
    	}
    }
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  3. #3
    Registered User
    Join Date
    Nov 2005
    Posts
    3

    Thumbs up Have to use Arrays.

    Testing it out.

    After test...

    It does gather all the information, but where it ends at the error in line 13, it crashes into line 14 and consoles both of them out wrong.

    My professor has us using array's because he wants us to eventually add more code to the program that will allow us to search for say, record by last name or record by employee number. From what I understand that will only work with using arrays.

    To answer two of your questions...

    1) No particular reason for not intializing i to zero. It's just a force of habit, although your way makes more sense and is less typing.

    2) I most likely won't need 10000 array values for the employee number, but that's just me venting my frustration with zeros.

    Idealy I'd like to be able stop printing line 13 at it's error and continue printing at line 14, or make things so that it will ignore the extra "intentionally wrong placed zipcode" and move onto the next correct data type which would be the state.

    Thank you for the ignore and clear pointers. It's already made my results a billion times better.
    Last edited by Eradicator; 11-22-2005 at 02:19 AM. Reason: Update

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Okay, first I don't know if its wrong, but I don't like the way you initialize the variable i. How about just "i = 0;".
    First of all, it would be:

    int i = 0;

    However, the line:
    Code:
    int i = int();
    calls the default constructor for an int type which initializes the int with 0. That's used for STL containers like vectors(which are very similar to arrays except they have no fixed size). If you declare a vector that has a specified size, the vector calls the default constructor for whatever element type it contains and fills the vector with the result. Therefore, all types need a default constructor for that to work. A vector of int's that is declared with a specified size will cause the vector to be filled with 0's.

    You can also do this:
    Code:
    int i(10);
    cout<<i<<endl;
    but I agree with you, it's much clearer if you just write:

    Code:
    int i = 0;
    int j = 10;
    Code:
    while(!finalData.eof())
    I hope your instructor didn't teach you to use a loop conditional like that for reading files. The basic rule for reading from a file is: the read statement should be a while loop conditional, e.g.
    Code:
    while( inputFile>>input)
    {
    	...
    	...
    }
    inputFile>>input calls a function that reads data into input, and then the function returns what's on the left side of the read statement, which in this case is inputFile, which converts the while conditional to:

    while(inputFile)

    If any errors occur that will prevent you from reading data from the file, the inputFile object will evaluate to false in the while conditional. End of file(eof) is considered an error, so the while loop will terminate correctly when you reach the end of the data in a file. However, there are other possible errors that can occur while reading from a file. If one of those errors occurs, then a loop such as:
    Code:
    while(!inputFile.eof())
    {
    
    }
    will try to keep reading data because it hasn't encountered eof yet--but the error will prevent the read statement from reading any data. So the loop will keep looping indefinitely, not being able to read in any data because of the error and never reaching eof.

    You have a long read statement, so it's going to make the while conditional very long. Just break it up over several lines that are all indented the same, so it looks neat.

    Idealy I'd like to be able stop printing line 13 at it's error and continue printing at line 14, or make things so that it will ignore the extra "intentionally wrong placed zipcode" and move onto the next correct data type which would be the state.
    I don't think you're going to be able to do that very easily. I think it requires reading in each piece of data in as a string, and then seeing if you can successfully convert it to the proper type. You could do that using stringstreams, but I don't know if you've studied them yet(or if you ever will).

    If you make your read statement the while loop conditional, then the program won't crash when it encounters bad input, the while loop will just terminate, and execution will continue with the rest of the program.
    Last edited by 7stud; 11-22-2005 at 04:45 AM.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    It would really probably be a better idea to read a line at a time and then split it. If you have the number of parts, you can then just check if they're the right count, and skip the line if they're not.

    Of course, splitting lines is not entirely trivial, unless you're allowed to use the Boost libraries. (But if you can do that, you might as well write a full-blown Spirit parser.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    The problem is that when you read the out of order data, it puts the file stream into a fail state that you need to clear before you can continue.

    IfYouSaySo's code is just about right for you. What you should do is to read into temporary variables. Make the read the control for an if statement:
    Code:
    if (finalData >> sEmployeeID >> sFirstName >> sLastName >> sMiddleInitial >> sState >> iZipCode >> iHours >> dRate)
    If the if succeeds, just put the temporary values into the array. In the else, which is run if the read fails (like it will on line 13), clear the stream and ignore up to the newline like IfYouSaySo's code does.

    With this setup, it is ok to use eof() to control your while loop because you will only be using the data if the read succeeds and the if is true. When the last line is read, it may go through the loop an extra time, but that will be ok because no extra data will be stored.

  7. #7
    Registered User
    Join Date
    Nov 2005
    Posts
    3

    Thumbs down "No," he says.

    So I put the results into my program to finish the project. When he sees my results he says, "No, I wanted you to read the data and configure your code so that it "ignores" just that "one" extra misplaced zipcode and continues to read till the end of file.

    I changed everything so that it all reads as arrays, just like he wanted. Still, he says the trick wasn't just to get the code to read all the data past the error, it was to get it ignore that one single error and capture "all" of the data.

    My "new" problem is getting to ignore just one bad array instead of ignoring to the end of the current line.

    000001 Moshiur Ahmed I CA 90805 40 12.50
    000002 Tasmia Amaat J CA 90706 35 25.60
    000003 Victor Barboza K CA 90706 42 30.00
    000004 Carlos Detorres I CA 90804 50 20.45
    000005 Tyree Ek O CA 90755 60 15.60
    000006 Amine El-Maziati M CA 90815 20 9.75
    000007 Loubna El-Maziati M CA 90815 25 10.50
    000008 Theresa Eyssallenne L CA 90715 40 20.00
    000009 Craig Griffith I CA 90804 40 45.00
    000010 Rodney Hallett H CA 90808 43 25.25
    000011 Andrew Hegstrom P CA 90808 45 13.50
    000012 Corey James D CA 90815 40 20.00
    000013 Farsio Kottab E 90013 CA 90755 40 20.00
    000014 Peter Lon W CA 90755 40 60.00
    000015 Joseph Lopes A CA 90808 50 100.00
    000016 Arley Lozada O CA 90280 50 30.40
    000017 Ana Moreno W CA 90805 55 14.50
    000018 Chris Myers Q CA 90802 57 30.00
    000019 Thanakom Paiboolsilp U CA 90805 56 45.75
    000020 Leonardo Priego P CA 90703 77 23.00

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <conio.h>
    using namespace std;
    
    void main()
    {
    	string arEmployeeID[300] = {""};
    	string arFirstName[300] = {""};
    	string arLastName[300] = {""};
    	string arMiddleInitial[100] = {""};
    	string arState[100] = {""};
    	int arZipCode[100] = {0};
    	int arHours[100] = {0};
    	double arRate[1000] = {0.0};
    
    	int i = 0;
    
    	ifstream finalData;
    	finalData.open("c:\\FinalData.txt");
    
    	while(!finalData.eof())
    	{	
    		if (finalData >> arEmployeeID[i] >> arFirstName[i] >> arLastName[i] >> arMiddleInitial[i] >> arState[i] >> arZipCode[i] >> arHours[i] >> arRate[i])
    		{
    			cout << arEmployeeID[i] << " " << arFirstName[i] << " " << arLastName[i] << " " << arMiddleInitial[i] << " " << arState[i] << " " << arZipCode[i] << " " << arHours[i] << " " << arRate[i] << " " << endl;
    			i++;
    		}
    		else if((finalData >> arEmployeeID[i] >> arFirstName[i] >> arLastName[i] >> arMiddleInitial[i] >> arState[i] >> arZipCode[i] >> arHours[i] >> arRate[i]).fail())
    		{
    			finalData.ignore();
    			finalData.clear();
    		}
    	}
    }

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    What you should do is to read into temporary variables. If the if succeeds, then put the temporary values into the array.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Meh. OK, I can see just about how this might work (although it will most likely lead to ugly code), but honestly, this requirement is dumb. No program tries to correct errors this way: if data is corrupted, then it's corrupted, and attempting to import it anyway is usually a baaaad idea.

    What you need to do is read every entry individually and check for errors after each one, repeating it when necessary. I'd advise you to write a template function for that, but I doubt you've done templates.
    Which means you should write three very similiar functions, one to read a string, one to read an integer, one to read a double.
    Oh, and you need additional validation: a string reader for the state code will not mind reading a zip code; you need to validate the input somehow. (Ask your teacher if it suffices checking that it's only uppercase letters or if you should actually list all US states.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Well, you can read it in line by line and then separate every line into pieces by space. And then you can check if the line is correct and if it isn't, just do the same thing with the next line.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 02:07 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21