I am writing a c++ function for reading the nth column of a tab delimited text file, here is what I have done:
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);
}
}
The problem is, in the bimReadCol
function, at the last line, after
in_file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
in_file.good()
still evaluates to true
. So, suppose I have a text file test.txt
like this:
a 1 b 2
a 1 b 2
a 1 b 2
bimReadCol("test.txt", 3)
would return a vector (b, b, b, b)
, with an extra element.
Any idea how to fix this?