How to input values from file

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • BenFedorko
    New Member
    • May 2010
    • 8

    How to input values from file

    Input file looks like this:

    5 Christine Kim...... 30.00 2 1 F
    15 Ray Allrich 10.25 0 0 M
    16 Adrian Bailey 12.50 0 0 F

    with exactly 20 characters from the start of the name to the null before the double.

    using
    Code:
    int empNum,
    		empDep,
    		empTyp;
    	char empNam[MAX_CHARS];
    	double empRat;
    	ifstream inEmp;
    
    	inEmp.open("master7.txt");
    	if (!inEmp)
    	{
    		cout << "\n\nError opening the file!!" << endl;
    		exit(1);
    	}
    
    	inEmp >> empNum;
    	inEmp.ignore(1, '\0');
    	inEmp.getline(empNam, MAX_CHARS); 
    	inEmp >> empRat >> empDep >> empTyp;
    	cout << "\nNum: " << empNum << "\nName: " << empNam[0] << empNam[1] << empNam[2]
    	<< "\nRat: " << empRat << "\nDep: " << empDep << "\nType :" << empTyp;
    	system("PAUSE");

    my output is as follows:
    Num: 5
    Name: Chr
    Rat: -9.25596e+61
    Dep: -858993460
    Type :-858993460Press any key to continue . . .


    why can't I get a good read for my double empRat?
  • BenFedorko
    New Member
    • May 2010
    • 8

    #2
    Originally posted by BenFedorko
    Input file looks like this:

    5 Christine Kim...... 30.00 2 1 F
    15 Ray Allrich 10.25 0 0 M
    16 Adrian Bailey 12.50 0 0 F

    with exactly 20 characters from the start of the name to the null before the double.

    using
    Code:
    int empNum,
    		empDep,
    		empTyp;
    	char empNam[MAX_CHARS];
    	double empRat;
    	ifstream inEmp;
    
    	inEmp.open("master7.txt");
    	if (!inEmp)
    	{
    		cout << "\n\nError opening the file!!" << endl;
    		exit(1);
    	}
    
    	inEmp >> empNum;
    	inEmp.ignore(1, '\0');
    	inEmp.getline(empNam, MAX_CHARS); 
    	inEmp >> empRat >> empDep >> empTyp;
    	cout << "\nNum: " << empNum << "\nName: " << empNam[0] << empNam[1] << empNam[2]
    	<< "\nRat: " << empRat << "\nDep: " << empDep << "\nType :" << empTyp;
    	system("PAUSE");

    my output is as follows:
    Num: 5
    Name: Chr
    Rat: -9.25596e+61
    Dep: -858993460
    Type :-858993460Press any key to continue . . .


    why can't I get a good read for my double empRat?
    Well I figured that part out.

    after I input the array of characters i used the "inEmp.clear(); " function like this:

    Code:
    	inEmp.ignore();
    	inEmp.getline(empNam,(MAX_CHARS));
    	emp[empCount].setName(empNam);
    	inEmp.clear();
    I still don't know why there was anything IN the buffer when I was done, maybe I need to use the cin.get() instead of cin.getline().

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      5 Christine Kim...... 30.00 2 1 F


      From this, there is:

      char 5
      char space
      char C
      char h
      char r
      char i
      char s
      char t
      char i
      etc...
      char 3
      char 0
      char .
      char 0
      char 0
      char space

      Where is the double and the int?

      Text files are char only. You will need to parse 30.00 as a string and convert that string to a double.

      Your only other choice is a binary file. There you can have the int and the double.

      However, you use getline that that only works with text files.

      Comment

      • BenFedorko
        New Member
        • May 2010
        • 8

        #4
        if I use "fin" as my file input stream I should be able to gather all of the data from this line using:

        Code:
        fin >> integerNumber;   // where this is an integer
        fin.getline(name, 20);    // character array
        fin >> doubleNumber;   // double
        fin >> integerNumber2; // integer
        fin >> integerNumber1; // integer
        fin >> characterF;        // character
        for some reason there was bad data in the buffer after I got the character array, once I used the inf.clear() function my other inputs worked just fine. I want to know why I need this function!

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          If this is your data:

          5 Christine Kim...... 30.00 2 1 F
          15 Ray Allrich 10.25 0 0 M
          16 Adrian Bailey 12.50 0 0 F

          then the fin >> integerNumber fetches the 5 and leave you positioned at trhe space right after the 5 and before the C. This is where your fin.getline(nam e, 20) will start. That means your 20 will stop one byte short of the 3. This is where
          fin >> doubleNumber will start. Since this position may be a text character and and not a double format, the >> will set the stream failbit.

          From this point on, every >> will fail becuse the the first thing >> does is check that failbit.

          You need to a) know where you are exactly in that inout record or b) reformat the record:

          5Christine Kim......30.00 2 1 F
          -<exactly 20 bytes..>

          Then after each >> operation, I would verify the failbit is not set. If it is, you need to reset the bit (the clear()) and then remove the offending data or the bit just gets set again:

          Code:
          fin >> integerNumber;
          if (fin.fail() == true)
          {
              //take corrective action or terminate the program
          }
          Personally, I would not use the getline(). Instead I would use >> to a string object. This will pick up the first name and stop at the space after the first name. Then I would use the another >> to pick up the last name.

          Remember the >> skips all whitespace characters.

          This means I would keep these strings separate as first name and last name.

          Comment

          • BenFedorko
            New Member
            • May 2010
            • 8

            #6
            Originally posted by weaknessforcats
            If this is your data:

            5 Christine Kim...... 30.00 2 1 F
            15 Ray Allrich 10.25 0 0 M
            16 Adrian Bailey 12.50 0 0 F

            then the fin >> integerNumber fetches the 5 and leave you positioned at trhe space right after the 5 and before the C. This is where your fin.getline(nam e, 20) will start. That means your 20 will stop one byte short of the 3. This is where
            fin >> doubleNumber will start. Since this position may be a text character and and not a double format, the >> will set the stream failbit.

            From this point on, every >> will fail becuse the the first thing >> does is check that failbit.

            You need to a) know where you are exactly in that inout record or b) reformat the record:

            5Christine Kim......30.00 2 1 F
            -<exactly 20 bytes..>

            Then after each >> operation, I would verify the failbit is not set. If it is, you need to reset the bit (the clear()) and then remove the offending data or the bit just gets set again:

            Code:
            fin >> integerNumber;
            if (fin.fail() == true)
            {
                //take corrective action or terminate the program
            }
            Personally, I would not use the getline(). Instead I would use >> to a string object. This will pick up the first name and stop at the space after the first name. Then I would use the another >> to pick up the last name.

            Remember the >> skips all whitespace characters.

            This means I would keep these strings separate as first name and last name.
            Thank you for your explanation that makes a lot of sense, I tried using the ignore() function but that didn't seem to work. According to your theory it should have though right?


            You said:
            "then the fin >> integerNumber fetches the 5 and leave you positioned at trhe space right after the 5 and before the C. This is where your fin.getline(nam e, 20) will start. That means your 20 will stop one byte short of the 3. This is where
            fin >> doubleNumber will start. Since this position may be a text character and and not a double format, the >> will set the stream failbit."

            but if after the
            "5 Christine Kim...... 30.00 2 1 F"
            line after the last "." is accepted and the cursor is to the left of the null character before "30.00," then a fin.ignore() or fin.ignore(\0) should behave like your clear function and my next fin should input the "30.00" properly. But it did not, do you have any ideas why?


            Also, this is for an assignment and so the professor asked us to keep all strings as arrays of characters (c-strings) and so I needed to input in that way. If there is a better way to fill the array with the input file information, by all means show me how! :) And of course I cannot change the input file either because of class restrictions.

            Thanks again.

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              If you need to use arrays of chars, then I would use cin.get() and fetch the name one byte at a time and store the byte in an element of the char array.

              Don't forget to add the \0 in the arrayfollowing the last byte of the name. That will make your array a C-string.

              If your name is guaranteed to have a non-text character after the first and last name, then you can use the >> operator with a char array for the first name and another char array for the last name.

              This is the same as using string objects but with no protection of the arrays.

              Comment

              • BenFedorko
                New Member
                • May 2010
                • 8

                #8
                Originally posted by weaknessforcats
                If you need to use arrays of chars, then I would use cin.get() and fetch the name one byte at a time and store the byte in an element of the char array.

                Don't forget to add the \0 in the arrayfollowing the last byte of the name. That will make your array a C-string.

                If your name is guaranteed to have a non-text character after the first and last name, then you can use the >> operator with a char array for the first name and another char array for the last name.

                This is the same as using string objects but with no protection of the arrays.
                Interesting. Thank you for the information, I appreciate it very much.

                Comment

                Working...