STL: std::ifstream 使用eof会多读一行数据

Share:
## Error Description STL: std::ifstream 使用eof会多读一行数据 ```cpp string dataset_dir = "Dataset_DIR"; cout << "dataset: " << dataset_dir << endl; ifstream fin("f3_w_static_associations.txt"); if (!fin) { cout << "please generate the associate file called associations.txt!" << endl; fin.close(); return 1; } vector rgb_files, depth_files; vector rgb_times, depth_times; while (!fin.eof()) { string rgb_time, rgb_file, depth_time, depth_file; fin >> rgb_time >> rgb_file >> depth_time >> depth_file; rgb_times.push_back(atof(rgb_time.c_str())); depth_times.push_back(atof(depth_time.c_str())); rgb_files.push_back(dataset_dir + "/" + rgb_file); depth_files.push_back(dataset_dir + "/" + depth_file); if (fin.good() == false) break; } fin.close(); ``` 我读取TUM数据集的时候,会发现会出现段错误: ```sh ************ Current Frame: 717 ************ terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr: __pos (which is 140) > this->size() (which is 0) Thread 1 "run_vo" received signal SIGABRT, Aborted. __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff4ac4e97 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007ffff4ac6801 in __GI_abort () at abort.c:79 #2 0x00007ffff511b957 in () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00007ffff5121ab6 in () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x00007ffff5121af1 in () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00007ffff5121d24 in () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x00007ffff511d855 in () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #7 0x00007ffff5dbc4e8 in () at /usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2 #8 0x00007ffff5daee64 in () at /usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2 #9 0x00007ffff5db476a in () at /usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2 #10 0x00007ffff5db532d in cv::imread(cv::String const&, int) () at /usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2 #11 0x0000555555558e5c in main(int, char**) (argc=, argv=) at /root/catkin_ws/src/aivslam/test/run_vo.cpp:66 (gdb) ``` 原因在于读取图像数据 cv::imread(cv::String const&, int)时,所传入的参数非法。 问题在于eof上。 在 https://blog.csdn.net/u011028345/article/details/76563198 博客上看到: > eof是end of file的意思,用来判断是否到了文件结尾。 按照一般思维,应该就是到达文件尾,就eof()应返回true,但事实上,在读完最后一个数据时,eofbit仍然是false。只有当流再往下读取时,发现文件已经到结尾了,才会将标志eofbit修改为true。这也就是为什么使用while(!readfile.eof())会出多现读一行的原因。 的确是这样的。 # Solution 使用 getline()或加上判空。 ## Example 1: ```cpp void LoadImages(const string &strAssociationFilename, vector &vstrImageFilenamesRGB, vector &vstrImageFilenamesD, vector &vTimestamps) { ifstream fAssociation; fAssociation.open(strAssociationFilename.c_str()); while (!fAssociation.eof()) { string s; getline(fAssociation, s); if (!s.empty()) { stringstream ss; ss << s; double t; string sRGB, sD; ss >> t; vTimestamps.push_back(t); ss >> sRGB; vstrImageFilenamesRGB.push_back(sRGB); ss >> t; ss >> sD; vstrImageFilenamesD.push_back(sD); } } } ``` ## Example 2: ```cpp // reading a text file #include #include #include using namespace std; int main () { string line; ifstream myfile ("example.txt"); if (myfile.is_open()) { while ( getline (myfile,line) ) { cout << line << '\n'; } myfile.close(); } else cout << "Unable to open file"; return 0; ``` ## My Example ```cpp string dataset_dir = "Dataset_DIR"; cout << "dataset: " << dataset_dir << endl; ifstream fin("f3_w_static_associations.txt"); if (!fin) { cout << "please generate the associate file called associations.txt!" << endl; fin.close(); return 1; } vector rgb_files, depth_files; vector rgb_times, depth_times; while (!fin.eof()) { string rgb_time, rgb_file, depth_time, depth_file; fin >> rgb_time >> rgb_file >> depth_time >> depth_file; if (!rgb_file.empty() && !depth_file.empty()) { rgb_times.push_back(atof(rgb_time.c_str())); depth_times.push_back(atof(depth_time.c_str())); rgb_files.push_back(dataset_dir + "/" + rgb_file); depth_files.push_back(dataset_dir + "/" + depth_file); } if (fin.good() == false) break; } fin.close(); if (rgb_files.size() != depth_files.size()) { cout << "RGB image size NOT equal to depth image size" << endl; return 1; ``` ![yubao_blog_cover](https://raw.githubusercontent.com/yubaoliu/assets/image/yubao_blog_cover.png)

No comments