I am trying to do some file reading with C++ in Ubuntu 16.04 (GCC&G++ 5.4 and CMake 3.5.1). The test file (named 123.txt) have only a line words just like this:
Reprojection error: avg = 0.110258 max = 0.491361
I just want to get the avg
error and max
error. My method is to get a line and put them into a std::string
and use string::find
. My codes are very easy just like this:
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
FILE *fp = fopen("123.txt", "r");
char tmp[60];
string str;
fgets(tmp, size_t(tmp), fp);
fclose(fp);
cout << tmp << endl;
str = tmp;
cout << str.size() << endl;
size_t avg = str.find("avg");
size_t max = str.find("max");
cout << avg << endl;
cout << max << endl;
}
I can use g++
to compile it successfully. But I meet a strange issue.
When I first run it in the command, it will get the right result:
Reprojection error: avg = 0.110258 max = 0.491361
52
20
37
If I run codes again, it will go wrong sometimes just like this:
p
2
18446744073709551615
18446744073709551615
The "p" is a disorderly code which can not be shown correctly in the command. I am not good at C++ and feel confused about it. Is there someone who can say something? Thank you!
The expression
fgets(tmp, size_t(tmp), fp);
is ill-formed, size_t(tmp)
will not work as you expect, you need sizeof(tmp)
.
The 52
value you get is because fgets
consumes the \n
character and this is counted too, actually the string has 51
characters counting with spaces.
That said, in this case you can use better C++ tools to replace the C ones you are using, fopen
can be replaced by using the fstream
library, fgets
can be replaced by getline
.
Something like:
#include <iostream>
#include <string>
#include <fstream>
int main()
{
std::ifstream fp("123.txt"); //C++ filestream
if (fp.is_open()) {//check for file opening errors
std::string str;
std::getline(fp, str); //C++ read from file
fp.close();
std::cout << str << std::endl;
std::cout << str.size() << std::endl;
size_t avg = str.find("avg");
size_t max = str.find("max");
std::cout << avg << std::endl;
std::cout << max << std::endl;
}
else{
std::cerr << "Couldn't open file";
}
}
Note that I dind't use using namespace std;
, this is for a reason, it's not a good practice, you can check this thread for more details.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.