【问题标题】:Getline Issue in C++C ++中的Getline问题
【发布时间】:2014-05-15 12:45:44
【问题描述】:

我有一个显示以下内容的文本文件:

John    Smith    21    UK
David   Jones    28    FRANCE
Peter   Coleman  18    UK

我正在尝试将每个单独的元素剥离成一个向量数组。我尝试使用带有制表符分隔符的 getline 函数,但它存储了每个元素。例如:

getline (f, line, '\t');
records.push_back(line);

如何逐行分隔?这个想法是执行搜索并输出相应的行。例如,搜索 Jones 将打印出第二行。

这是我目前所拥有的,但正如你所见,它并没有给我想要的结果:

string sString;
string line;
string tempLine;
string str;
vector<string> records;

cout << "Enter search value: " << endl;
cin >> sString;

cout << "\nSEARCHING\n\n";
ifstream f("dataFile.txt");

while (f)
    {
    while(getline (f, tempLine))
    {
       getline (f, line, '\t');
       records.push_back(line);
    }
    for(int i=0; i < records.size(); i++)
    {
       if(sString == records[i]) {
        cout << "RECORD FOUND" << endl;
        for(int j=0; j < records.size(); j++)
        {
            cout << j;
            cout << records[j] << "\t";
        }
        }
    }

}
f.close();

【问题讨论】:

  • 我想我不是很清楚。我希望它将行中的每个单词存储到一个数组中,检查数组中的字段是否与搜索字符串(sString)匹配,如果匹配,则打印出数组。然后它再次为下一行重复该过程,依此类推
  • 我不清楚你想在你的向量中添加什么。你能举个例子说明records[0]应该是什么字符串等吗?
  • 你的意思是向量应该包含与字符串匹配的所有行吗? (类似于grep)?
  • 当然。记录[0] = 约翰,记录[1] = 史密斯,记录[2] = 21,记录[3] = 英国。我试图弄清楚如何获取每个单词并将其存储在数组中,直到它命中 \n,对数组执行我需要的操作,清除数组并从下一行开始。这有意义吗?

标签: c++ getline


【解决方案1】:

第一个getline 从输入中提取完整的一行。 第二个从下一行中提取一个字段。如果你想 要恢复分解为字段的行,您应该这样做:

std::vector<std::vector<std::string>> records;
std::string line;
while ( std::getline( f, line ) ) {
    records.push_back( std::vector<std::string>() );
    std::istringsream fieldParser( line );
    std::string field;
    while ( std::getline( fieldParser, field ) ) {
        records.back().push_back( field );
    }
}

这将产生一个记录向量,其中每条记录是 字段向量。更多时候,你会想要使用一个结构 作为记录,并在行上进行更多解析,例如:

struct Field
{
    std::string firstName;
    std::string lastName;
    int age;
    std::string country;
};
std::vector<Field> records;
std::string line;
while ( std::getline( f, line ) ) {
    std::istringsream fieldParser( line );
    Field field;
    fieldParser >> field.firstName >> field.lastName >> field.age >> field.country >> std::skipws;
    if ( !fieldParser || fieldParser.get() != EOF ) {
        //  Error occurred...
    } else {
        records.push_back( field );
    }
}

(这种简单的方法只有在没有任何字段可以的情况下才有效 包含空格。但是很容易扩展。)

【讨论】:

    【解决方案2】:

    您正在将 getline 转换为 tempLine ,这会占用一整行,然后您也在循环中执行不同的 getline。这就是为什么它不起作用的很大一部分原因——您只是在丢弃包含大量数据的 tempLine

    【讨论】:

    • 我现在可以看到了。感谢您指出了这一点!我想我正试图弄清楚如何获取每个单词并将其存储在数组中,直到它命中 \n,对数组执行我需要的操作,清除数组并从下一行开始。那有意义吗?这让我很困惑
    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多