如何消除这个额外的因素
How to eliminate this extra element?
本文关键字:何消 更新时间:2023-10-16
我正在编写一个c++函数,用于读取以制表符分隔的文本文件的第n列,以下是我所做的:
typedef unsigned int uint;
inline void fileExists (const std::string& name) {
if ( access( name.c_str(), F_OK ) == -1 ) {
throw std::string("File does not exist!");
}
}
size_t bimNCols(std::string fn) {
try {
fileExists(fn);
std::ifstream in_file(fn);
std::string tmpline;
std::getline(in_file, tmpline);
std::vector<std::string> strs;
strs = boost::split(strs, tmpline, boost::is_any_of("t"), boost::token_compress_on);
return strs.size();
} catch (const std::string& e) {
std::cerr << "n" << e << "n";
exit(EXIT_FAILURE);
}
}
typedef std::vector<std::string> vecStr;
vecStr bimReadCol(std::string fn, uint ncol_select) {
try {
size_t ncols = bimNCols(fn);
if(ncol_select < 1 or ncol_select > ncols) {
throw std::string("Your column selection is out of range!");
}
std::ifstream in_file(fn);
std::string tmpword;
vecStr colsel; // holds the column of strings
while (in_file) {
for(int i=1; i<ncol_select; i++) {
in_file >> tmpword;
}
in_file >> tmpword;
colsel.push_back(tmpword);
in_file.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
return colsel;
} catch (const std::string& e) {
std::cerr << "n" << e << "n";
exit(EXIT_FAILURE);
}
}
问题是,在bimReadCol
函数中,在
in_file.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
in_file.good()
仍为true
。所以,假设我有一个文本文件test.txt
,像这样:
a 1 b 2
a 1 b 2
a 1 b 2
bimReadCol("test.txt", 3)
将返回一个带有额外元素的向量(b, b, b, b)
。知道怎么解决这个问题吗?
面向行输入的通常解决方案是按行读取,然后解析每一行:
std::string line;
while ( std::getline( in_file, line ) ) {
std::istringstream parser( line );
for ( int i = 1; parser >> tmpword && i <= ncol_select; ++ i ) {
}
if ( parser ) {
colsel.push_back( tmpword );
}
// No need for any ignore.
}
重要的是,您必须在之后测试输入(无论是来自in_file
还是parser
),然后使用价值。在读取值之前进行测试没有任何意义(如你所见)
好的,我知道了。文本文件的最后一行不包含换行符,这就是计算in_file
的原因到true
的最后一行
我想我应该计算文件的行数,然后用a替换while(in_file)
for循环。
如果有人有更好的主意,请贴出来,我会接受的。
更新修复结果相当简单,只需检查tmpword
是否为空:
vecStr bimReadCol(std::string fn, uint ncol_select) {
try {
size_t ncols = bimNCols(fn);
if(ncol_select < 1 or ncol_select > ncols) {
throw std::string("Your column selection is out of range!");
}
std::ifstream in_file(fn);
vecStr colsel; // holds the column of strings
std::string tmpword;
while (in_file) {
tmpword = "";
for(int i=1; i<=ncol_select; i++) {
in_file >> tmpword;
}
if(tmpword != "") {
colsel.push_back(tmpword);
}
in_file.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
return colsel;
} catch (const std::string& e) {
std::cerr << "n" << e << "n";
exit(EXIT_FAILURE);
}
}
正如@James Kanze所指出的,即使最后一行包含换行in_file
仍然会评估为true
,但由于我们在文件的末尾,下一次读取到tmpword
将是空的,所以只要我们检查一下就可以了。
相关文章:
- 函数何时会在c++中包含stack_Unwind_Resume调用
- Python中的for循环与C++有何不同
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 在C++中释放内存期间,迭代器与指针有何不同
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 类中的 C++ int 被设置为值,似乎不知从何而来
- -fvisibility-inline-hidden 与 gcc 中的 -fvisibility=hidden 有何不同
- SDL_LockTexture() / 地址消毒液 / 双免
- 收益率和回报有何不同?
- 覆盖私有功能,它与受保护功能有何不同?
- Visual Studio 2017中的哪些扩展在传入lambda时消除了"bool"与"std::function"的歧义?
- 擦除删除成语的性能增益从何而来
- 无论代码长度如何,以下代码的内存要求有何不同?
- "virtual"对C++析构函数有何影响?
- 如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
- 系统时间从何而来?
- stl::unordered_map 和 stl::vector 的销毁有何不同
- C++ 友元函数在内存位置上有何不同?
- 为什么我可以在不链接任何额外库的情况下包含 sys/*.h
- C 是否具有接口类概念,如果它在那里,那么它与Java接口类别有何不同