views:

130

answers:

2

I'm writing a program for an exercise that will read data from a file and format it to be readable. So far, I have a bit of code that will separate a header from the data that goes under it. Here it is:

int main() {
    ifstream in("records.txt");
    ofstream out("formatted_records.txt");
    vector<string> temp;
    vector<string> headers;
    for (int i = 0; getline(in,temp[i]); ++i) {
        static int k = -1;
        if (str_isalpha(temp[i])) {
            headers[++k] = temp[i];
            temp.erase(temp.begin() + i);
        }
        else {
            temp[i] += "," + headers[k];
        }
    }
}

(str_isalpha() is just a function that applies isalpha() to every character in a string.) Now, the for-loop in this program doesn't execute, and I can't figure out why. Does anybody know?

EDIT: As suggested, I changed it to

string line;
for (int i = 0; getline(in,line); ++i) {
    temp.push_back(line);

Still skips the for-loop altogether.

+5  A: 

vector<string> temp; makes an empty vector. When you then try to read into temp[0], that is undefined behavior. You should pass as getline's second argument a separate string variable, say string foo; before the loop, then temp.push_back(foo); as the first instruction in the loop's body.

Alex Martelli
+4  A: 

If the loop still doesn't run after ensuring that you're reading into a valid string reference, then you should check that the stream you're reading from is valid. The stream will be invalid if the file doesn't exist or if you lack permission to read it, for instance. When the stream isn't valid, getline won't read anything. Its return value is the same stream, and when converted to bool, it evaluates as false. Check the stream's status before proceeding.

ifstream in("records.txt");
if (!in.is_open()) {
  std::cerr << "Uh-oh.\n";
  return EXIT_FAILURE;
}
Rob Kennedy
Thanks, this turned out to be the problem.
Maulrus