4

I'm working on a function that reads in lines of a file until the line "XXX" is reached in the file, and a counter keeps track of how many lines have been read. Then the program counts the remaining number of lines in the file. I'm using an if statement to determine when to break the while loop (when the line read equals "XXX") and the condition is not being met. Even when line == "XXX", the else statement will still run. What's wrong with my code? Thanks!

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

using std::string;
using std::endl;
using std::cout;
using std::ifstream;

int main()
{ 
    //Main function
}

void read_file(string input_file_name)
{
    string i_filename = input_file_name;
    ifstream infile;
    infile.open (i_filename);
    string line;
    int num_of_terms1 = 0;
    int num_of_terms2 = 0;

    if (!infile)
    {
        cout << "Your input file could not be opened."<<endl;
    }
    else
    {
        while (!infile.eof())
        {
            getline(infile, line);
            cout << line << endl;

            if (line == "XXX")
            {
                break;
            }
            else
            {
                cout << line << endl;
                num_of_terms1++;
            }
        }
        while (!infile.eof())
        {
            getline(infile, line);
            cout << line << endl;
            num_of_terms2++;
        }
    }
cout << "Terms 1: "<<num_of_terms1 <<endl;
cout << "Terms 2: "<< num_of_terms2 <<endl;
infile.close();
}

Here's a sample input file, inputfile.txt:

-2 3
4 2
XXX
-2 3

Thanks in advance for your help!

14
  • What does the output look like? Commented Oct 14, 2014 at 17:59
  • 1
    Why don't you do some debugging. Start by inspecting the values of line on each iteration of the loop. Your real problem is not that the program doesn't work, but that you have not learnt how to debug. Once you do so you can solve all these problems yourself. Commented Oct 14, 2014 at 18:00
  • Why do you think that "Even when line == "XXX", the else statement will still run" ? Commented Oct 14, 2014 at 18:00
  • 1
    Did you check for spaces, carriages, etc.? Commented Oct 14, 2014 at 18:00
  • 2
    while (!infile.eof()) Related: Why is iostream::eof inside a loop condition considered wrong? Commented Oct 14, 2014 at 18:06

3 Answers 3

4

I tested this code on www.compileonline.com and repeated your findings.

In that environment each string read from the file has a \r character on the end of it.

When I changed the terminating line to if (line == "XXX\r") the code worked as expected.

It seems that your input file's lines are terminated with "\r\n" which is the norm for windows, but unix text files are normally terminated with '\n'.

Update:

Here's a little demo of how one might remove trailing carriage returns and linefeeds (or anything else you want for that matter):

#include <string>
#include <algorithm>
#include <iostream>

void trim_cruft(std::string& buffer)
{
    static const char cruft[] = "\n\r";

    buffer.erase(buffer.find_last_not_of(cruft) + 1);
}

void test(std::string s)
{
    std::cout << "=== testing ===\n";
    trim_cruft(s);
    std::cout << s << '\n';
}

int main()
{
    test("");                   // empty string
    test("hello world\r");      // should trim the trailing \r
    test("hello\nworld\r\n");   // don't trim the first newline
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I tried with "XXX\n" but I didn't realize "\r" would do it. I really appreciate the help.
I feel that it's important that you understand what's going on here. Embedding \r in your test string will make this work on windows but not on unix. It's better to clean any control characters off the string you read before testing it.
Amazing! Thanks a lot for explaining the details in a clear fashion.
1

First of all you should read this: Why is iostream::eof inside a loop condition considered wrong?

Second your debug lines:

cout << line << endl;

are exactly the same in both cases - you are inside else statement or you are counting num_of_terms2 and it is confusing. Change them, so you can see which one is printed.

After you fix that issues you will see that "else statement will not still run"

Comments

0

As I said in the comments, you have 2 cout statements you should verify which one is printing the XXX. If none of them are, then it is likely the problem is that there is a carriage return in the string, you can verify this other case with:

cout << line << endl; // print is here

if (line == "XXX\r")
{
    break;
}
else
{
    cout << line << endl; // print is here
    num_of_terms1++;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.