C ++读取具有多个分隔符的文件

时间:2016-05-17 21:13:13

标签: c++ delimiter file-handling

我有以下文本文件。

的text.txt

1, Harry Potter, 1998, UK/trains/wizards/

要求用户输入图书的名称,然后输入发布日期,并列出与图书相关联的所有关键字。用户可以输入的关键字数量没有限制。此数据将在具有私有成员的类中使用,以便可以更改或删除等。

我想知道如何阅读文本文件,该文本文件将分割1个哈利波特1998和每个关键字(如英国火车向导)之间的每一行。

下面的代码读取文件并根据设置的分隔符将其拆分。是一种方法来推荐这个使用多个分隔符,或者是为第一批数据创建一个文件和为keyowrds创建另一个文件的简单解决方案吗?

std::ifstream file("test.txt");
std::string line;
if (file)
{
    std::string token;
    std::stringstream ss;

    while (getline(file, line))
    {
        ss << line;

        while (getline(ss, token, ','))
        {   
            std::cout << token << std::endl;
        }
        ss.clear();
    }
}

5 个答案:

答案 0 :(得分:1)

不要对逗号分隔的字段使用循环。为关键字使用循环。

std::string token1 = getline(ss, token1, ','); // 1
std::string token2 = getline(ss, token2, ','); // "Harry Potter"
std::string token3 = getline(ss, token3, ','); // 1998
std::vector<string> keywords;
std::string word;
while (getline(ss, word, '/'))
{
  keywords.push_back(word);
}

您需要根据逗号分隔符限制提取次数。由于您的示例中只有3列,因此实际上不需要循环。

答案 1 :(得分:0)

简单的解决方案是完成您在关键字标记上的逗号分割所做的工作:

std::vector parseKeywords(const std::string & keywords)
{
    std::vector result;
    std::stringstream keywordstrm(token);
    std::string keyword;
    while (getline(keywordstrm, keyword, '/'))
    {
        result.push_back(keyword);
    }
    return result;
}

答案 2 :(得分:0)

您可以扩展遍历任意数量字段的while循环,并使用内循环中的第二个分隔符进一步中断每个字段:

while (getline(file, line)) {
    ss << line;
    while (getline(ss, token, ',')) {   
        std::stringstream ss2(token);   // parse now the field that was read    

        while (getline(ss2, tok2, '/'))  // and decompose it again
           std::cout << tok2 << " + ";
        std::cout << std::endl; 
    }
    ss.clear();
}

Online demo

您可以使用向量而不仅仅是字符串来存储多值字段。

答案 3 :(得分:0)

假设您知道文本文件的确切格式,Thomas Matthews solution可能更好,但对于您不知道的更一般情况......您可以尝试此解决方案,它适用于任何一组定界符,它就像getline一样......

std::istream& getline2(std::istream& stream, std::string& s, const std::string& delimeters){
    s.clear(); char c;
    while(stream.read(&c, 1)){
        if(delimeters.find(c) != std::string::npos)
            break;
        s += c;
    }
    return stream;
}

示例用法:

while (getline2(ss, token, ",/\."))
{   
    std::cout << token << std::endl;
}

此处使用案例的完整代码on Coliru

答案 4 :(得分:0)

在这种情况下使用strtok

  

`std::ifstream file("test.txt");
std::string line;
if (file)
{
    std::string token;
    std::stringstream ss;

    while (getline(file, line))
    {

        char * pch;
        pch = strtok (str.c_str()," ,.-");
        while (pch != NULL)
       {
         std::cout<<pch<<std::endl;
         pch = strtok (NULL, " ,.-");
       }
                ss.clear();
    }
}`