逐行读入文本文件中的数据,用C ++中的多个分隔符分隔

时间:2015-03-18 21:05:25

标签: c++ file text delimiter getline

我有一个文本文件中的数据,我希望将其读入并拆分,然后创建一个新对象。

我找到了这段代码:

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,后面是

任何帮助将不胜感激!感谢。

2 个答案:

答案 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)