Loop stop condition not working due to "invisible" characters

Hello I am currently reading a file that has a format like this:
2.5437667456 0.38745628423 0.342573653788 2
0.538756284345 -1.37875463465 -3.474745747457 2
-3.324632463248 5.24528346425 3.897894329744 2
1.932842347523 2.78497477934 -1.533467646355 1
2.7843215284 1.64355764345 3.378673675634 1
-3.238902347923 2.89093423532 1.634667357634 1


or basically, series of three floating point values followed by a integer.

What I am trying to accomplish it is to ignore the lines that end with 2 and process the others. To do this I am retriving each line with getline and throwing it in a string. Then I put the stop condition as line[size-1] = '2' .

And it works.....for the first lines. In the first line where it don't work, I print line [size-1] and all that shows up it is nothing, like the last character it is a the blank space character. Then I changed the stop condition to line[size-1] = '2' || line[size-2] = '2' || line[size-3] = '2'.
And it worked..........for a few couple of lines more. Then I came to a line
where if a print the values of line[size-1] and line[size-2] and line[size-3] nothing shows up again.

Once again I changed the stop condition to (line[i-1] = ' ' || line[i] = '2' || line[i+1] = ' ') || line[size-1] == '2') with the idea to stop the loop whenever I don't find the substring " 2 ", doesn't mattering if there are more than one blank character at the end of the string or if '2' is the last character, in which case there will be only the substring " 2".
It didn't work.

So what I need it is: a way to print the asc2 values to know which "invisible" characters that are troubling me so I can adjust the stop condition. I think printf can work, but would like to now if there is something in c++.
Or then some method that can solve it automatically. It was suggested fscanf, but again I would prefer a c++ solution. Plus a prefere to solve it more "manually" as I have been trying to do.

Finally I would like to know how it is possible that these "invisible" characters don't show up in a text editor. I opened it with gedit and writer from OpenOffice and in both the last character in each line it is 2
Last edited on
try == instead of =
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::ifstream in("Somefile.txt");
std::string line;
std::istringstream parser;
while(std::getline(in, line)) { //read line

    parser.str(std::move(line));
    double x, y, z;
    int i;
    parser >> x >> y >> z >> i; //Separate line into 3 doubles and int

    if(parser.fail() || i == 2) //Go to the next iteration if line in wrong format or ends in 2
        continue;

    //Use x y z
}
Thanks for the replies. Konstantin2, I used == in place of =, it were just typos.
MiiNiPaa, I can't test your code due to move not being supported on my compiler.
Anyway, my main goal is to find out why the strings that getline are retrieving are different from what I see in a text editor. Any ideas about it?
They have some spaces at the end of strings?
I haven't tested this, but it should show you the ASCII values of the "invisible" characters you're getting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <fstream>
#include <string>

int main()
{
	std::string str;
	std::ifstream fin("input.txt");
	unsigned int line = 0;
	while (std::getline(fin, str))
	{
		++line;
		std::string::size_type pos = str.find_last_of("0123456789+-.");
		std::string invis = str.substr(pos + 1);
		std::cout << "Line " << line << ": ";
		for (auto c: invis)
			std::cout << static_cast<int>(c) << ' ';
		std::cout << std::endl;
	}
	fin.close();
	return 0;
}
MiiNiPaa, generally yes.
fg109; I got the following errors:
||16|error: expected initializer before ':' token|
[19|error: expected primary-expression before '}' token|
|19|error: expected ')' before '}' token|
|19|error: expected primary-expression before '}' token|
|19|error: expected ';' before '}' token|
||=== Build finished: 5 errors, 0 warnings ===|

Last edited on
due to move not being supported on my compiler.
I got the following errors:
2011 was four years ago, plenty time to update. Any modern compiler should support C++11. Are you sure that it is not the you forgotting to turn support on?

In my code you can just remove std::move. As it just eliminates copy.

IN fg109 code you will need to read up on ranged-for and translate it to old school for manually.


They have some spaces at the end of strings?
MiiNiPaa, generally yes.
So, why are you surprised when you access last symbol in line which ends with several spaces and it is not digit?
My gcc is from 2010, so I guess not

I am surprised because there is nothing there after the number two on two different text editors


P.S: I changed
1
2
for (auto c: invis)
			std::cout << static_cast<int>(c) << ' ';


to
1
2
for (int i=0; i<invis.size(); i++)
			std::cout << static_cast<int>(i) << ' ';


and tested it on the file. The result was awkward. No line with the pattern of three floating point values followed by an integer showed anything. The only line that showed anything was a line with the number 1070 that produced this output:
Line 3: 0 1 2 3 4 5 6 7
. Not sure if the code it is correct.
Last edited on
That would need to be std::cout << static_cast<int>(invis[i]) << ' ';

And it's not supposed to show anything unless there is something between the last digit on the line and the end of the line.
Last edited on
Ok I tested it with invis[i] and nothing changed. That means there is nothing after the digit 2 in the file lines? If that it is the case, why the stop condition line[size-1] == '2' doesn't work after a certain line? The size it is x and the '2' should be in position size-1, right?

This line:
-0.72745241760641044 -0.68569273924452645 -0.025263664578695975 2
is where the stop condition (line[i] == '2' && line[i-1] == ' ' && line[i+1] == ' ') || line [size-1] == '2') fails
I put these commands
1
2
3
4
5
6
7
8
cout << "line [size-3]: " << line [size-3] <<  endl;
        cout << "line [size-2]: " << line [size-2] <<  endl;
        cout << "line [size-1]: " << line [size-1] <<  endl;
        cout << "line [size]: "   << line [size]   <<  endl;
        cout << "line [size+1]: " << line [size+1] <<  endl;
        cout << "line [i-1]:    " << line [i-1]    << endl;
        cout << "line [i]:      " << line [i]      << endl;
        cout << "line [i+1]:    " << line [i+1]    << endl; 
after the while loop ends and it is printed:
line [size-3]:
line [size-2]: 2
line [size-1]:
line [size]:
line [size+1]:
line [i-1]:
line [i]: 2
line [i+1]:
on the screen. How this it is possible if the code with static casting is saying that there is nothing after the '2' character? (as well as the text editors). Here cout is telling that the '2' is in one position of the string before the last one, that's why the loop ends, but why nothing shows up in fg109 code or in a text editor? I am totally lost here
It might be the way you are reading your string are affecting it, or you are writing file on Windoes and opening it on Linux, or something else.

Use formatted input ( stream >> something ) to avoid most problems.
Topic archived. No new replies allowed.