【发布时间】:2014-09-16 09:46:45
【问题描述】:
我正在编写一个用于读取制表符分隔文本文件的第 n 列的 c++ 函数,这是我所做的:
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::exception 派生
-
@DieterLücking 您能否提供有关返回值与异常的参考?我不知道如何将返回值用于与异常相同的目的。
-
不,但在我看来
fileExists当然不应该抛出异常。 -
哦,那个。但为什么不呢?
-
@DieterLücking 我刚刚发现创建一个带有自定义错误消息的异常类太麻烦了,所以我想,为什么不直接抛出一个错误消息呢?你能解释一下为什么这很糟糕吗?