I don't understand the mistake I am making here. Can someone help explain the output? and how to correct it?

Expected output
ABC54301 TFTFTFTT TFTFTFFTTFT

Actual output
ABC54301

inFile
1
2
3
4
5
6
7
8
9
TFFTFFTTTTFFTFTFTFTT
ABC54301 TFTFTFTT TFTFTFFTTFT
ABC64301 TFTFTFTT TFTFTFFTTFT
ABC74301 TFTFT FTFFFTTTFTFTFT
ABC84301 TFTFTFTTTTFTF TTTFFF 
ABC94301 TFTFTFTTFFTFTFTFTFTF
ABC14301 TFTFT FTTFFFTTTTFTTF
ABC24301 TFTFTFTTTTFTFT FFFTT
ABC34301 TF TTTFFFTFTFTFFFTTT 




Code for program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <array>

#define SIZE 64
using namespace std;

int main(int argc, const char * argv[])
{


    ifstream inFile;
    inFile.open("inFile.txt", ifstream::in);
    if (!inFile) {
        cerr << "Error: in file could not be opened" << endl;
        return -1;
    }
    int count = 0;
    string line[SIZE];
    if (inFile.is_open()) {
        while (getline(inFile, line[SIZE -1], '\n')) {
            inFile >>  line[count];
            count ++; 
        }
        inFile.close();
    }
    
    cout << line[1];


The way I am reading this..

1
2
3
4
5
if (inFile.is_open()) {
        while (getline(inFile, line[SIZE -1], '\n')) {
            inFile >>  line[count];
            count ++; 
        }


if the infile is open.
while - get lines from input stream(infile) save to string array. line delimiter is new line char.

So I would expect this to save the entire line into my line array.
what am I overlooking here? Thanks in advance.
Try changing this:
23
24
25
26
        while (getline(inFile, line[SIZE -1], '\n')) {
            inFile >>  line[count];
            count ++; 
        }

to this:
23
24
    while (getline(inFile, line[count++]))
        ; // empty loop body 
I am sorry can you expand a little bit on what was going wrong with my code? Thank you so much. I just want to understand what is happening here. I have some idea. but just missing the context of what my code was doing wrong and how your code fixes my mistake. I want to understand what I was logically and systematically doing to get the incorrect output.
Last edited on
Well, this line: getline(inFile, line[SIZE -1], '\n') is reading a line from the file and storing it in the last row of the array;

After that, inFile >> line[count]; is reading the next word (as far as the first whitespace character) into consecutive rows of the array.

So your code was doing something like this:

getline: TFFTFFTTTTFFTFTFTFTT // all of line 1
cin >>: ABC54301              // first part of line 2
getline: TFTFTFTT TFTFTFFTTFT // remainder of line 2 
cin >>: ABC64301              // first part of line 3
getline: TFTFTFTT TFTFTFFTTFT // remainder of line 3
cin >>: ABC74301              // first part of line 4
etc...

This while unexpected it would honestly work out good for me. would there be a reliable way to access the "remainders" given the set of code and and input file? Thanks again for your input. This is very helpful.

EDIT. I think I get this... working on solution.
Last edited on
Rather than an array, I used a vector here. For my own convenience in testing, I used a stringstream rather than a file, but the behaviour of both types of stream should be equivalent.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>

    using namespace std;

int main()
{
    string data =
        "TFFTFFTTTTFFTFTFTFTT\n"
        "ABC54301 TFTFTFTT TFTFTFFTTFT\n"
        "ABC64301 TFTFTFTT TFTFTFFTTFT\n"
        "ABC74301 TFTFT FTFFFTTTFTFTFT\n"
        "ABC84301 TFTFTFTTTTFTF TTTFFF\n"
        "ABC94301 TFTFTFTTFFTFTFTFTFTF\n"
        "ABC14301 TFTFT FTTFFFTTTTFTTF\n"
        "ABC24301 TFTFTFTTTTFTFT FFFTT\n"
        "ABC34301 TF TTTFFFTFTFTFFFTTT\n";

    istringstream inFile(data);

    vector<string> lines;
    string line;
    string dummy;

    while(getline(inFile,line))
    {
        lines.push_back(line);
        inFile >> dummy; // read and discard next word
        inFile >> ws;    // discard any whitespace
    }

    // Output the contents of the vector
    for (unsigned int i=0; i<lines.size(); i++)
    {
        cout << setw(4) << i << " " << lines[i] << endl;
    }

    return 0;
}


Output:
   0 TFFTFFTTTTFFTFTFTFTT
   1 TFTFTFTT TFTFTFFTTFT
   2 TFTFTFTT TFTFTFFTTFT
   3 TFTFT FTFFFTTTFTFTFT
   4 TFTFTFTTTTFTF TTTFFF
   5 TFTFTFTTFFTFTFTFTFTF
   6 TFTFT FTTFFFTTTTFTTF
   7 TFTFTFTTTTFTFT FFFTT
   8 TF TTTFFFTFTFTFFFTTT
Here is my final soution. Thanks for your help. It gave me the traction I needed!

Here is the explanation out of the book I am going through.

The history teacher at your school needs help in grading a True/False test. The students’ IDs and test answers are stored in a file. The first entry in the file contains answers to the test in the form:
TFFTFFTTTTFFTFTFTFTT
Every other entry in the file is the student ID, followed by a blank, followed by the student’s responses. For example, the entry:
ABC54301 TFTFTFTT TFTFTFFTTFT
indicates that the student ID is ABC54301 and the answer to question 1 is True, the answer to question 2 is False, and so on. This student did not answer question 9. The exam has 20 questions, and the class has more than 150 students. Each correct answer is awarded two points, each wrong answer gets one point deducted, and no answer gets zero points. Write a program that processes the test data. The output should be the student’s ID, followed by the answers, followed by the test score, followed by the test grade. Assume the following grade scale: 90%–100%, A; 80%–89.99%, B; 70%–79.99%, C; 60%–69.99%, D; and 0%–59.99%, F


input
1
2
3
4
5
6
7
8
9
TFFTFFTTTTFFTFTFTFTT
ABC54301 TFFTFFTTTTFFTFTFTFTF
ABC64301 FFFFTFTT TFTFTFFTTFT
ABC74301 TFTFT FTFFFTTTFTFTFT
ABC84301 TFTFTFTTTTFTF TTTFFF 
ABC94301 TFTFTFTTFFTFTFTFTFTF
ABC14301 TFTFT FTTFFFTTTTFTTF
ABC24301 TFTFTFTTTTFTFT FFFTT
ABC34301 TF TTTFFFTFTFTFFFTTT 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <fstream>
#include <string>
#include <array>
 
#define SIZE 64
 
using namespace std;
 
char grader(string studentsoution, string actualsoution);
 
int main(int argc, const char * argv[])
{
 
    ifstream inFile;
    inFile.open("inFile.txt", ifstream::in);
    if (!inFile) {
        cerr << "Error: in file could not be opened" << endl;
        return -1;
    }
    // open file and read line by line.
    int count = 0;
    string line[SIZE];
 
    if (inFile.is_open()) {
        while (getline(inFile, line[count++], '\n')) {
        }
        inFile.close();
    }
 
    //splitting line into sub strings.
    string studentID[SIZE], studentSolutions[SIZE];
    for (int i = 1; i < count -1 ; i++) {
        studentSolutions[i] = line[i].substr(9);
        studentID[i] = line[i].substr(0,8);
        cout << studentID[i] << " points grade is... "
        << grader(studentSolutions[i].c_str(), line[0].c_str())
        << endl;
    }  
   
 
    return 0;
}
 
char grader(string studentsoution, string actualsoution){
 
    int DeductPoints = 0;
    for (int i = 0; i < actualsoution.length(); i++) {
        if ( studentsoution.at(i) != actualsoution.at(i)) {
            DeductPoints++;
            i++;
        }
    }
    double totalpoints = 20 - DeductPoints;
    int grade = totalpoints / 20*100;
    char letterGrade = '\0';
    switch(grade/10)
        {
                case 9: letterGrade = 'A';
            break;
                case 8: letterGrade = 'B';
            break;
                case 7: letterGrade = 'C';
            break;
                case 6: letterGrade = 'D';
                default:
            letterGrade = 'F';
        }
    return letterGrade;
}


output

1
2
3
4
5
6
7
8
ABC54301 points grade is... A
ABC64301 points grade is... C
ABC74301 points grade is... F
ABC84301 points grade is... C
ABC94301 points grade is... C
ABC14301 points grade is... F
ABC24301 points grade is... C
ABC34301 points grade is... F
Last edited on
Topic archived. No new replies allowed.