[英]C++ Read file line by line then split each line using the delimiter
我想逐行读取一个txt文件,并且在阅读完每一行之后,我想根据选项卡“ \\ t”拆分行,并将每个部分添加到结构中的元素中。
我的结构是1 * char和2 * int
struct myStruct
{
char chr;
int v1;
int v2;
}
其中chr可以包含多个字符。
一行应该是这样的:
randomstring TAB number TAB number NL
尝试:
注意:如果chr可以包含多个字符,则使用字符串表示。
std::ifstream file("plop");
std::string line;
while(std::getline(file, line))
{
std::stringstream linestream(line);
std::string data;
int val1;
int val2;
// If you have truly tab delimited data use getline() with third parameter.
// If your data is just white space separated data
// then the operator >> will do (it reads a space separated word into a string).
std::getline(linestream, data, '\t'); // read up-to the first tab (discard tab).
// Read the integers using the operator >>
linestream >> val1 >> val2;
}
除非您也打算将此结构用于C,否则我将用std :: string替换预期的char *。
接下来,由于我打算能够从流中读取它,因此我将编写以下函数:
std::istream & operator>>( std::istream & is, myStruct & my )
{
if( std::getline(is, my.str, '\t') )
return is >> my.v1 >> my.v2;
}
以str作为std :: string成员。 这将使用tab作为第一个定界符写入您的结构,然后任何空格定界符都会在接下来的两个整数之前执行。 (您可以强制它使用选项卡)。
要逐行阅读,您可以继续阅读这些内容,或者先将一行阅读为一个字符串,然后将该字符串放入istringstream中并调用上面的内容。
您将需要决定如何处理失败的读取。 上面任何失败的读取都将使流处于失败状态。
std::ifstream in("fname");
while(in){
std::string line;
std::getline(in,line);
size_t lasttab=line.find_last_of('\t');
size_t firsttab=line.find_last_of('\t',lasttab-1);
mystruct data;
data.chr=line.substr(0,firsttab).c_str();
data.v1=atoi(line.substr(firsttab,lasttab).c_str());
data.v2=atoi(line.substr(lasttab).c_str());
}
我在遵循这里的一些建议时遇到了一些困难,因此我发布了一个完整的示例,该示例在制表符分隔的文件上重载结构的输入和输出运算符。 另外,它还可以从stdin
或通过命令参数提供的文件中获取输入。
我相信这很简单,只要遵守操作符的语义即可。
成对
#ifndef PAIRWISE_VALUE
#define PAIRWISE_VALUE
#include <string>
#include <iostream>
struct PairwiseValue
{
std::string labelA;
std::string labelB;
float value;
};
std::ostream& operator<<(std::ostream& os, const PairwiseValue& p);
std::istream& operator>>(std::istream& is, PairwiseValue& p);
#endif
成对的
#include "pairwise.h"
std::ostream& operator<<(std::ostream& os, const PairwiseValue& p)
{
os << p.labelA << '\t' << p.labelB << '\t' << p.value << std::endl;
return os;
}
std::istream& operator>>(std::istream& is, PairwiseValue& p)
{
PairwiseValue pv;
if ((is >> pv.labelA >> pv.labelB >> pv.value))
{
p = pv;
}
return is;
}
测试文件
#include <fstream>
#include "pairwise.h"
int main(const int argc, const char* argv[])
{
std::ios_base::sync_with_stdio(false); // disable synch with stdio (enables input buffering)
std::string ifilename;
if (argc == 2)
{
ifilename = argv[1];
}
const bool use_stdin = ifilename.empty();
std::ifstream ifs;
if (!use_stdin)
{
ifs.open(ifilename);
if (!ifs)
{
std::cerr << "Error opening input file: " << ifilename << std::endl;
return 1;
}
}
std::istream& is = ifs.is_open() ? static_cast<std::istream&>(ifs) : std::cin;
PairwiseValue pv;
while (is >> pv)
{
std::cout << pv;
}
return 0;
}
编译中
g++ -c pairwise.cc test.cc
g++ -o test pairwise.o test.o
用法
./test myvector.tsv
cat myvector.tsv | ./test
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.