3

所以我有一个带有接收文件名的函数的 .cpp 文件,并且应该返回一个带有文件内容的字符串(实际上修改了内容,我修改了代码以使其更易于理解,但这对我的问题)。问题是f.good()正在返回false并且读取文件的循环不起作用。代码 :

#include "StdAfx.h"
#include "Form21.h"
#include <string>
#include <fstream>
#include <iostream>



    string ReadAndWrite(char* a){
    char filename[8];
    strcpy_s(filename,a);
    string output;
    char c;
    ifstream f(filename,ios::in);
    output+= "Example text"; // <-- this writes and returns just fine!
    c = f.get();

    while (f.good())
      { 

    output+= c;
    c= f.get();         
          }

    return output;
}

有谁知道为什么会这样?它是否与这是一个单独的 .cpp 文件有关(当我删除它时它甚至不会抛出错误#include <fstream>)。也许有一种不同的方法来制作循环?我很高兴听到有关如何解决此问题的任何建议,或者关于如何实现我的目标的不同方法。

4

3 回答 3

4

首先,实际上没有理由复制您收到的文件名——您可以按原样使用它。其次,几乎任何形式的循环while (stream.good())while (!stream.bad())while (stream),等等,几乎肯定是有问题的。您通常想要做的是检查读取某些数据是否有效。

或者,您可以完全跳过使用循环。有几种方法可以做到这一点。一个适用于较短文件的文件如下所示:

string readfile(std::string const &filename) { 
    std::ifstream f(filename.c_str());   
    std::string retval;

    retval << f.rdbuf();
    return retval;
}

这可以很好地处理数十千字节(左右)的数据,但在处理较大的文件时会开始减慢速度。在这种情况下,您通常希望使用ifstream::read以下一般路线来获取数据:

std::string readfile(std::string const &filename) {
    std::ifstream f(filename.c_str());

    f.seekg(0, std::ios_base::end);
    size_t size = f.tellg();

    std::string retval(size, ' ');
    f.seekg(0);
    f.read(&retval[0], size);
    return retval;
}

编辑:如果您需要处理单个字符(而不仅仅是阅读它们),您有几个选择。一种是将其分成多个阶段,在一个阶段中读取所有数据,并在单独的阶段中进行处理。另一种可能性(如果您只需要在处理过程中查看单个字符)是使用类似std::transform读取数据、进行处理并将输出放入字符串的方法:

struct character_processor { 
    char operator()(char input) { 
        // do some sort of processing on each character:
        return ~input;
    }
};

std::transform(std::istream_iterator<char>(f),
               std::istream_iterator<char>(),
               std::back_inserter(result),
               character_processor());
于 2012-04-24T15:57:08.853 回答
0

我会检查 strlen(a) 是否不大于 7...您可能会溢出filename并获得一个不存在的文件名。

不涉及问题,我会重新编写函数:

string ReadAndWrite(string a) {  // string here, if you are into C++ already
    string filename;  // also here
    filename = a;  // simpler
    string output;
    char c;
    ifstream f(filename.c_str());  // no need for ios::in (but needs a char *, not a string
    output+= "Example text"; // <-- this writes and returns just fine!
    f >> c;  // instead c = f.get();

    while (f) // no need for f.good())
      { 

        output+= c;
        f >> c; // again, instead c= f.get();         
      }

    return output;
}
于 2012-04-24T15:45:24.143 回答
-3

我可以建议使用 fopen 吗?http://www.cplusplus.com/reference/clibrary/cstdio/fopen/它接受一个文件名并返回一个文件指针。有了它,您可以使用 fgets 逐行读取文件http://www.cplusplus.com/reference/clibrary/cstdio/fgets/

于 2012-04-24T15:46:14.657 回答