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