我的fstream是坏还是不好()?

时间:2012-04-24 15:39:00

标签: c++ iostream fstream

所以我有一个带有函数的.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>时它甚至不会抛出错误)。 也许有一种不同的方法来制作循环? 我会很高兴听到有关如何解决这个的任何建议,或许是一种不同的方法来实现我的目标。

3 个答案:

答案 0 :(得分: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());

答案 1 :(得分: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;
}

答案 2 :(得分:-3)

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