我在一个文件中有行,每行中的每行都用空格分隔。这是一个简化的线条示例:
208 "Person" "Anne Myers" "unsigned long" "hello" -1 false false false
在单个字段中,某些单词由空格分隔。即“安妮迈尔斯”。这是解析的问题。
有什么建议吗?输出应该是9个字段,以便进一步处理。 在我的情况下,用某些字符替换字段内的空格是不可行的。
编辑:所有行都遵循相同的字段顺序。
答案 0 :(得分:0)
一个可能的起点是一个重载operator>>
以便以这种格式正确读取数据的类型:
class field {
std::string content;
public:
friend std::istream &operator>>(std::istream &is, field &f) {
char ch;
// skip whitespace, then read one character
is >> ch;
// If it's a quote, read to the next quote
if (ch == '"')
std::getline(is, f.content, '"');
else {
// otherwise put it back, and read until white-space:
is.unget();
std::getline(is, f.content);
}
return is;
}
// While we're at it, I'm going to define output so we can see what was
// read in a single field easily:
friend std::ostream &operator<<(std::ostream &os, field const &f) {
return os << "[" << f.content << "]";
}
};
然后我们可以为单行定义记录类型,将该类型用于适当的字段:
struct foo {
int a;
field b;
field c;
field d;
field e;
int f;
bool g, h, i;
friend std::istream &operator>>(std::istream &is, foo &f) {
return is >> std::boolalpha
>> f.a
>> f.b
>> f.c
>> f.d
>> f.e
>> f.f
>> f.g
>> f.h
>> f.i;
}
friend std::ostream &operator<<(std::ostream &os, foo &f) {
return os << std::boolalpha
<< f.a << " "
<< f.b
<< f.c
<< f.d
<< f.e << " "
<< f.f << " "
<< f.g << " "
<< f.h << " "
<< f.i;
}
};
然后我们可以测试阅读和写一条记录:
int main() {
std::istringstream in
{ R"(208 "Person" "Anne Myers" "unsigned long" "hello" -1 false false false)" };
foo f;
in >> f;
std::cout << f;
}
结果:
208 [Person][Anne Myers][unsigned long][hello] -1 false false false
这(目前)不会尝试处理也包含引号的字段。这可能是使用类似C的约定,我们使用反斜杠转义引号,或类似CSV的约定,其中我们通过在输入中的一行中放入两个引号来包含一个引号。
例如:
"Bill said: ""Go away""!"
...将被解析为一个字段,包含文本:
Bill said: "Go away"!
要么很容易添加,要么你没有说要支持哪个(如果有的话),所以我暂时把它留了出来。