C++ 标准:ofstrean不';不要与-O3一起工作
下面的代码很简单 1) 从命令行参数中获取输入文件名,例如in.txt 2) 将文件名附加到“cdf_3;” 3) 打开一个新名称为cdf_in.txt的文件 4) 只需从(每行中的一个数字)中读取每一行并将其发送到输出文件C++ 标准:ofstrean不';不要与-O3一起工作,c++,fstream,C++,Fstream,下面的代码很简单 1) 从命令行参数中获取输入文件名,例如in.txt 2) 将文件名附加到“cdf_3;” 3) 打开一个新名称为cdf_in.txt的文件 4) 只需从(每行中的一个数字)中读取每一行并将其发送到输出文件 #include <iostream> #include <fstream> #include <cstring> using namespace std; int main(int argc, char* argv[]) { c
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char *ben = argv[1]; // example: in.txt
ifstream fin (ben);
char res[30];
char *o1 = "cdf_";
strcat(res, o1);
strcat(res, ben);
ofstream fout (res, std::ofstream::out); // will be cdf_in.txt
cout << res << endl;
uint64_t num; uint64_t sum = 0;
while (fin >> num) {
fout << num << endl;
}
return 0;
}
为什么fout
不能与-O3
一起使用?您的strcat(res,o1)
依赖于res[0]='\0'
,这可能是真的,但不能保证(res
是未初始化的本地,因此其内容未知/未指定)
当您不进行优化时,它很可能被初始化为零,但当您进行优化时,它不会被初始化为零
您可以通过初始化res
,或使用strcpy
而不是strcat
来修复要复制到那里的第一个项目(但这仍然会留下可能的缓冲区溢出问题,请参阅下文以获得更好的替代方案)
或者,当然,你可以编写代码更像C++而不是C,使用<代码> STD::String < /C> >代替char数组。
std::string fname("cdf_");
fname += argv[1];
std::ofstream fout(fname.c_str()); // just `fout(fname)` with a C++11 compiler
如果出于某种原因确实想编写类似C的代码,那么在本例中使用sprintf
可能更容易:
char res[30];
sprintf(res, "cdf_%35s", argv[1]);
std::ofstream fout(res);
如果将所有
char*
替换为std::string
,会发生什么情况?有时,-O3
可能会暴露在标准编译时隐藏的或太低而看不见的泄漏。如果可以,请使用Valgrind检查您的程序以搜索泄漏。版本为GCC-4.4。6@vsoftco:fstream中的文件名应为char*如果无法打开文件,继续该程序有什么意义吗?例如,如果无法打开输出文件,执行读/写循环的意义是什么(考虑到您未定义的行为,这可能会导致整个程序格式错误)。如果有些东西可能会失败,你应该经常检查失败,最好早点养成这个好习惯。仅供参考,如果我像charres[30]=“a”那样初始化
同样的事情发生在-O3
上。没有这样的文件…好的。首选C++方法。Thanks@mahmood:毫无疑问(至少在我看来),问题出在您用来生成文件名的代码中。生成文件名后,您将向std::ofstream
的ctor
传递一个字符串,该字符串通常与优化级别完全相同。
char res[30];
sprintf(res, "cdf_%35s", argv[1]);
std::ofstream fout(res);