我有一个文本文件中的数据,我希望将其读入并拆分,然后创建一个新对象。
我找到了这段代码:
std::ifstream file("plop");
std::string line;
while(std::getline(file, line))
{
std::stringstream linestream(line);
std::string data;
int val1;
int val2;
std::getline(linestream, data, '\t');
linestream >> val1 >> val2;
}
其中读取文本文档并将其拆分。但是,此代码假定分隔符始终是制表符。如果数据有多个分隔符会指向跟随它的数据类型,该怎么办?即假设一个文本文件,如:
hey, "hi" (hello) [hola]
bye, "by" (byeee) [biii]
我希望将数据拆分为
String twoCharacters;
String threeCharacters;
String fourCharacters;
String fiveCharacters;
所以
twoCharacters = hi and by
分隔符是两个" 和
threeCharacters = hey and bye
,分隔符为a,后面是
任何帮助将不胜感激!感谢。
答案 0 :(得分:1)
您可以继续使用不同的分隔符调用std::getline()
:
std::ifstream file("test.txt");
std::string line;
while(std::getline(file, line))
{
std::stringstream linestream(line);
std::string skip;
std::string item1;
std::string item2;
std::string item3;
std::string item4;
std::getline(linestream, item1, ',');
std::getline(linestream, skip, '"');
std::getline(linestream, item2, '"');
std::getline(linestream, skip, '(');
std::getline(linestream, item3, ')');
std::getline(linestream, skip, '[');
std::getline(linestream, item4, ']');
if(linestream) // true if there were no errors reading the stream
{
std::cout << item1 << '\n';
std::cout << item2 << '\n';
std::cout << item3 << '\n';
std::cout << item4 << '\n';
}
}
我使用变量skip
来读取下一个字段的开头。
答案 1 :(得分:0)
您可以使用std::istream::sentry
执行此操作。虽然有点复杂,但几乎可以完全控制数据的输入方式。
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <map>
std::istream& operator>>(std::istream& is,
std::map<std::string, std::vector<std::string> >& map) {
std::istream::sentry s(is);
if(s) {
// your accumulator
std::string str1;
// while your stream is good keep appending data
while(is.good()) {
// get the next character in the stream
char c = is.get();
// if it is a comma append the data to the "three" vector
if(c == ',') {
map["three"].push_back(str1);
// if it is a comma get all of the data until the next comma
} else if(c == '"') {
std::string str2;
str2 += c;
c = is.get();
while(c != '"') {
str2 += c;
c = is.get();
}
str2 += c;
map["two"].push_back(str2);
// do the same thing for parenthases
} else if(c == '(') {
std::string str2;
str2 += c;
c = is.get();
while(c != ')') {
str2 += c;
c = is.get();
}
str2 += c;
map["five"].push_back(str2);
// do the same thing for square brackets
} else if(c == '[') {
std::string str2;
str2 += c;
c = is.get();
while(c != ']') {
str2 += c;
c = is.get();
}
str2 += c;
map["four"].push_back(str2);
// append to your accumulator if you get an alphanumeric char
} else if(std::isalnum(c)) {
str1 += c;
// clear your accumulator if you get a return
} else if(c == '\n') {
str1.clear();
}
}
}
return(is);
}
int main() {
std::ifstream file("plop");
// make your map to hold your data
std::map<std::string, std::vector<std::string> > map;
map["two"] = std::vector<std::string>();
map["three"] = std::vector<std::string>();
map["four"] = std::vector<std::string>();
map["five"] = std::vector<std::string>();
// read your data
file >> map;
// print your data
std::vector<std::string> words{"two", "three", "four", "five"};
for(auto x: words) {
std::cout << x << std::endl;
for(auto y: map[x]){
std::cout << '\t' << y << std::endl;
}
}
}
这应该打印
two
"hi"
"by"
three
hey
bye
four
[hola]
[biii]
five
(hello)
(byeee)