Getline只返回空白

时间:2015-10-26 22:18:25

标签: c++ file-io vector getline

我正在尝试连续打开多个文件。文件名都存储在一个向量中,该向量将传递给我的函数。这只是一个简单的测试,以确保一切正常。如果它有效,那么我将需要将文件保存的任何内容推回到另一个向量中。

void readfile(vector<string> &filename)
{
    string temp;
    ifstream infile(filename[2].c_str());
    getline (infile, temp);
    cout << temp << endl;
}

这只是输出一个空白行,尽管文本文件包含一段信息。我有一段时间没有使用过File I / O,所以我有点生疏了。任何帮助表示赞赏。

编辑:你们都得到了很大的帮助,还有一件事,我需要在没有句号或空格的情况下传递它们。基本上只是一串字符。

2 个答案:

答案 0 :(得分:1)

OP的代码不检查任何文件IO是否成功,因此文件可能没有打开,文件可能为空,并且读取可能由于多种原因而失败。

幸运的是,getline返回输入流,并且流实现了一个非常简洁的运算符bool,如果流处于错误状态且无法读取,则返回false。如果无法读取文件,则temp的内容肯定无效,不应使用。

因此...

void readfile(vector<string> &filename)
{
    string temp;
    ifstream infile(filename[2].c_str());
    if (getline (infile, temp)) //test the read for success
    {
        cout << temp << endl;
    }
    else
    {
        cout << "failed to read file" << endl;
    }    
}

如果getline因任何原因失败,包括文件未打开,文件为空,文件已损坏且无法读取,则流的状态将标记为错误,并在if()检查时返回false。

通常在这一点上你应该检查错误类型,infile.clear()流来删除错误条件,然后拿起碎片,但在这种情况下没有多大意义。如果您无法将文件的开头读入字符串,则会出现大问题,应该仔细查看文件filename[2]的运行状况和内容。

顺便说一句,如果您的编译器是相对最新的,ifstream的构造函数将使用std :: string并且ifstream infile(filename[2]);将是有效的。

样式方面,你最好只将文件名字符串传递给readfile,而不是向量。这允许您重用readfile函数,而不仅仅是向量的元素2。

void readfile(string & filename)
{
    string temp;
    ifstream infile(filename);
    if (getline (infile, temp)) //test the read for success
    {
        cout << temp << endl;
    }
    else
    {
        cout << "failed to read file " << filename << endl;
    }    
}

打电话
readfile(filename[2]);

扩展此功能以满足OP的真正目标

void readfile(string & filename,
              vector<string> & strings)
{
    string temp;
    ifstream infile(filename);
    if (getline (infile, temp)) //test the read for success
    {
        strings.push_back(temp);
        cout << temp << endl;
    }
    else
    {
        cout << "failed to read file " << filename << endl;
    }    
}

并致电

vector<string> strings;
...
readfile(filename[2], strings);

答案 1 :(得分:0)

您的函数假定文件名向量中至少有三个元素,并忽略除第三个(元素2)之外的所有文件名。

此外,对getline()的调用只读取文件的第一行行 - 可能是一个空行。

我建议您编写一个函数来提取单个文件的内容,并在循环中使用它(在另一个函数中?)来处理文件名列表中的每个文件名。

相关的,&#39;文件名&#39;意味着一个文件名; &#39;文件名&#39;最好表明你的变量是多个文件名。

// Return file content as a single string
string readfile( const string& filename )
{
  ifstream f( filename );
  stringstream ss;
  ss << f.rdbuf();
  return ss.str();
}

// Return file content as a vector/deque/whatever of strings
deque<string> readfile( const string& filename )
{
  ifstream f( filename );
  deque<string> lines;
  string line;
  while (getline( f, line )) lines.emplace_back( line );
  return lines;
}

未报告错误。 (你只有一个空字符串/ vector / deque / etc。)

在循环中的其他地方使用它。在这里,我有一个文件名 - &gt;文件数据的地图,在文件名列表中加载每个文件名:

for (const string& filename : filenames)
  filedata[ filename ] = readfile( filename );

希望这有帮助。