【问题标题】:How to use std::getline() to read a text file into an array of strings in C++?如何使用 std::getline() 将文本文件读入 C++ 中的字符串数组?
【发布时间】:2013-10-01 18:29:45
【问题描述】:

我试图在我的项目中使用std::getline() 将文本文件读入字符串数组。

这是我的代码:

ifstream ifs ( path );
string * in_file;
int count = 0;
while ( !ifs.eof() )
{
    ++count;
    if ( count == 1 )
    {
        in_file = new string[1];
    }
    else
    {
            // Dynamically allocate another space in the stack
    string *old_in_file = in_file;
    in_file = new string[count];
            // Copy over values
    for ( int i = 0 ; i < ( count - 1 ) ; i++ )
    {
        in_file[i] = old_in_file[i];
    }
    delete[] old_in_file;
    }
            // After doing some debugging I know this is the problem what am I 
            // doing wrong with it?
    getline(ifs,in_file[count - 1]);
}

所以在做了一些解码之后,我知道 getline() 没有在字符串数组中放置任何值。它似乎在数组中放置了一个空字符串。

目标是读取文本文件,例如:

Hello
Bye
See you later

数组将被填充为:

in_file [0] = Hello
in_file [1] = Bye
in_file [2] = See you later

【问题讨论】:

  • 如果你的任务允许你使用std::vector,你应该这样做而不是new'ing 和delete'ing 每次迭代。
  • 在 StackOverflow 中搜索“解析 getline 读取文件”。这个问题被问了太多次了。

标签: c++ arrays file-io fstream dynamic-arrays


【解决方案1】:

永远不要使用以下循环来包装从流中读取的内容:

while ( !ifs.eof() )

在一些网站上,你会发现一个例子告诉你这样做:

while ( ifs.good() )

这比第一个循环要好一些,但仍然很容易出错并且不建议这样做。看看:Why is iostream::eof inside a loop condition considered wrong?

读取文件最常见的方法是在逐行读取时使用std::getline

std::string line;
while ( std::getline(ifs, line) ) {
    if (line.empty())                  // be careful: an empty line might be read
        continue;                      
    ...
}

或在按单词阅读或提取具体类型(例如数字)时简单地使用&gt;&gt; 运算符:

std::string word;
while ( ifs >> word ) {               
    ...
}

对于动态分配的std::string 对象数组:尽可能避免动态分配。相信我,你不想自己处理内存管理。更喜欢使用具有自动存储持续时间的对象。充分利用标准库提供的功能。
正如已经指出的那样:使用 STL 容器,例如 std::vector,而不是 C 样式的数组:

std::ifstream ifs(path);
std::vector<std::string> lines;

std::string line;
while ( std::getline(ifs, line) )
{
    // skip empty lines:
    if (line.empty())
        continue;

    lines.push_back(line);
}

【讨论】:

  • 我知道这行得通,但我对使用std::getline 的结果作为while 循环的条件感到困惑。 std::getline 返回的流如何导致循环继续或停止?
  • while ( std::getline(ifs, line) ) 如果您需要在多线程环境中使用锁同步访问流
【解决方案2】:

为什么这么麻烦?

只需使用std:vectorstd::string

std::string str;

std::vector <std::string> vec;

while ( std::getline(ifs,str) )
{
  vec.push_back(str) ;
}

如果你真的需要string的数组

做:

string * in_file = new string[vec.size()];

并将vec中的元素复制到in_file

for(size_t i=0;i<vec.size();i++)
 in_file[i] = vec[i];

【讨论】:

    猜你喜欢
    • 2017-09-12
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    相关资源
    最近更新 更多