stuck on a problem..

Here is the code I have so far.

data file
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 



main 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>

#define SIZE 255
using namespace std;

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


    ifstream inFile;
    inFile.open("inFile", ifstream::in);
    if (!inFile) {
        cerr << "Error: file could not be opened" << endl;
        return -1;
    }

    // reading file line by line // EOF = no chars;
    string line[SIZE];
    int i = 0;
    while (inFile.good()) {
        getline(inFile, line[i], '\n');
        cout << line[i] << " line// " << i << endl;
        i++;
    }
    cin.clear();
    
    string grades[SIZE];
    char anwsers[SIZE][SIZE];
    for (int i = 1,k = 0; i < line[i].length(); i++, k++) {
        while (cin.good()) {
             cin >> grades[0] >> anwsers[k][SIZE];
        }
       
    }

    cout << anwsers[2][SIZE] << endl << endl; 

    ofstream outFile;
    outFile.open("outData.txt", ifstream::out);
    if (!outFile) {
        cerr << "Error: file could not be opened" << endl;
        return -2;
    }

    return 0;
}


I am stuck attempting to execute this block
1
2
3
4
5
6
7
8
    string grades[SIZE];
    char anwsers[SIZE][SIZE];
    for (int i = 1,k = 0; i < line[i].length(); i++, k++) {
        while (cin.good()) {
             cin >> grades[0] >> anwsers[k][SIZE];
        }
       
    }


Algorithmically speaking I would like to iterate through the data file
from the second line down (already stored line by line in an array) and break up cin into to parts per line.

pesudo

loop from +1 on the array..
for each line
cin >> string var >> char array
if '\n' found increment loop.
What is in the input file? The first line is different. Why?
The following lines have varying number of words. What is its meaning?
In other words, describe the format of inFile.

What does come from standard input?
In other words, describe the expected format of cin input.

Once you get the data, how will it be used?
Sorry I do not want to reveal too much about what I am doing (because I would like to solve the program my self. So sorry if I am vague.)

Algorithmically what I would like to code this point is that I am having issues with is.

in pesudo...
1
2
3
4
k = 0
i = 1
for loop starting with line[i]
cin >> grades[k] >> anwsers[i]


Last edited on
Why do I get a feeling that you don't actually want to read from std::cin?

I will pretend that the problem is this:
* First line of input file has N characters from set {'T','F'}. This is a reference entry.

* All other lines have first an unique identifier, then one whitespace, and last an entry of N characters from set {'T','F',' '}.

* Each entry is compared to the reference, and something is computed. The result is shown with the identifier.

std::valarray, while out of fashion, would make certain step easy. That, however, I bet to not be the objective of the assignment. Nevertheless, "Valarray operators" has (non-spoiling) example for thought.

Back to input. You already have istream& getline (istream& is, string& str); in use. Now, I would peak into std::istringstream. Then I would read the identifier and one dummy char from a line via the istringstream. The rest: getline(). That places the "entry" into a std::string with the spaces intact.

For extra points, which are apparently forbidden from students, the use of a POD struct or std::map would be lovely. Seriouosly, your attempts to index your various arrays does need much more attention.
You nailed the what the data file is doing. While I am a student. This is not homework this is a exercise out of book that I am doing. The section is on arrays.. here is another take on solving the issue that is stated above.

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
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>

#define SIZE 255
using namespace std;

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


    ifstream inFile;
    inFile.open("inFile", ifstream::in);
    if (!inFile) {
        cerr << "Error: file could not be opened" << endl;
        return -1;
    }

    // reading file line by line // EOF = no chars;
    string line[SIZE];
    int i = 0;
    while (inFile.good()) {
        getline(inFile, line[i], '\n');
        cout << line[i] << " line// " << i << endl;
        i++;
    }
    cin.clear();
    
    char studentID[SIZE][SIZE];
    string grades[SIZE][SIZE];
    for (int i = 1, k = 0; line[i].length(); i++, k++) {
        cin >> studentID[k][SIZE] >> grades[k][SIZE];
    }

    ofstream outFile;
    outFile.open("outData.txt", ifstream::out);
    if (!outFile) {
        cerr << "Error: file could not be opened" << endl;
        return -2;
    }

    return 0;
}


where this will not output any thing to common output

cout << studentID[2] << endl << grades[2][1];



Not sure if you could offer any advise with in the code I a providing? Or anyone else?
Last edited on
Line 6. C++ supports const global variables. Safer than preprocessor macros.

Lines 23-24 could be:
1
2
while ( i < SIZE && getline( infile, line[i] ) )
{

Reasoning:
1. You don't want to read more than your line can hold.
2. The returned values of getline() and good() are effectively same in conditional.

Line 28 is not useful. std::cin has no place in this party.

1
2
std::string studentID[SIZE];
char grades[SIZE][SIZE];

Both could be 1-D string arrays, but you want to learn.

Lines 32-34. No.
1. The end condition of the loop is scary; first element of line that is an empty string.
2. If array has SIZE elements, then array+SIZE is one past the end.
3. std::cin still has no part in this party.

What you probably want is to iterate over the lines, except the first one.
( int row = 1; row < i; ++row )

Ok, now you have one line from inFile, line[row]. What do you want?
To split that line into studentID and grade.
More specifically, to store them to studentID[row] and grades[row]. Just remember that element 0 in each array is empty.

How to split? One could use the std::stringstream, or do as the chars do.

Loop over line[row] in phases. This is a nested loop within the outer iteration's body.

In first phase proceed only up to the first space. Append each character into string studentID[row]. std::string has operator+=(char).

Second phase copies the rest of characters into grades
grades[row][x] = line[row][col];
Note how col advances from 0 to line[row].size(). You don't want x to grow to SIZE though. Add a null '\0' to grades after the last written character.

Test output:
1
2
3
4
for ( int row = 1; row < i; ++row )
{
  std::cout << studentID[row] << " got " << grades[row] << std::endl;
}

Last edited on
Topic archived. No new replies allowed.