-1

I am having a slight issue when reading from a file in C++, the reason for the function is to find a line that has the characters v and a space at the beginning of it.

It is finding line correctly, but when trying read numbers from the file, it is always outputting 0.

Here is the code for the function

Model::Model(std::string fileName) {
    std::ifstream reader;

    reader.open(fileName);

    float temp1 = 0, temp2 = 0, temp3 = 0;

    if (reader.is_open()) {
        std::string line;

        while (reader.eof() != true) {
            getline(reader, line);

            if (line.substr(0, 2) == "v ") {
                reader >> temp1 >> temp2 >> temp3;

                std::cout << temp1 << " | " << temp2 << " | " << temp3 << std::endl;
            }
        }
    }
    else {
        std::cerr << "Error opening the file at path " + fileName;
    }
}

It is reading from the file fine, and is printing all well, but the temp variables are staying at 0 for some reason.

Anyone know how to fix this? Or any ideas as to why this is happening?

My only idea is that the stream for some reason is getting bad input, but that wouldn't make too much sense.

Any help appreciated!

Rocky
  • 19
  • 1
  • 1
    The shown code in this question fails to meet stackoverflow.com's requirements for a [mre], and because of that it is unlikely that anyone here can determine the problem. This question must be [edit]ed to show a minimal example, no more than one or two pages of code (the "minimal" part), that anyone can cut/paste, compile, run, and reproduce the described problem (the "reproducible" part) ***exactly as shown*** (this includes any ancillary information, like the input to the program). See [ask] for more information. – Sam Varshavchik Apr 04 '20 at 23:02
  • 1
    Relevant read: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Algirdas Preidžius Apr 04 '20 at 23:33
  • 1
    It would help to show a sample of the input file – M.M Apr 04 '20 at 23:56

2 Answers2

0

I think you need to convert each read character to integer. So add the following temporary variables:

char temp1_char, temp2_char, temp3_char;

and do:

reader >> temp1_char>> temp2_char>> temp3_char;
temp1 = (temp1_char- '0' ) % 48;
temp2 = (temp2_char- '0') % 48;
temp3 = (temp3_char- '0') % 48;
std::cout << temp1 << " | " << temp2 << " | " << temp3 << std::endl;

Also, try replacing:

while (reader.eof() != true)

with:

while (getline(reader, line))

You didn't mention how the file that you want to read from is structured. Provide a snippet from the file showing some lines containing "v " and what you want to be stored in temp1, temp2 and temp3. And provide some lines where the condition is not met.

Khaled Ismail
  • 175
  • 1
  • 14
0

In your code, getline(reader, line) extracts a line of input from reader and places it into line. Then, when a line of input meets your condition, it proceeds to extract further input from reader. However, the extraction continues at the next line. And, so attempting reader >> temp1 >> temp2 >> temp3 fails. As a result, any and all subsequent attempts to extract data will fail.

I would suggest using std::stringstream together with std::getline to parse your line of input. For example, first use getline(reader, line) to get your line of input into line. Then, if it meets your condition, store the string into the string stream. Then extract the string from the string stream into variables.

By the way, as others have already suggested, you can use getline(reader, line) as your condition for your while loop. The returned stream is converted to True when successful. Otherwise, it is converted to False.

Model::Model(std::string fileName) {

    std::ifstream reader;
    reader.open(fileName);

    if (reader.is_open()) {

        float temp1 = 0, temp2 = 0, temp3 = 0;
        std::string temp, line;
        std::stringstream ss;

        while (std::getline(reader, line)) {
            if (line.substr(0, 2) == "v ") {
                ss << line;
                ss >> temp >> temp1 >> temp2 >> temp3;
                std::cout << temp1 << " | " << temp2 << " | " << temp3 << std::endl;
                ss.clear();
            }
        }

    }
    else {
        std::cerr << "Error opening the file at path " + fileName;
    }
}
Domenic
  • 5,857
  • 2
  • 6
  • 14