The following code, simply
以下代码,简单地说
1) takes an input file name from the command line argument, say in.txt
1)从命令行参数中获取输入文件名,比如in.txt
2) append the file name to "cdf_"
2)将文件名附加到“cdf_”
3) open a file with new name cdf_in.txt
3)打开一个名为cdf_in.txt的文件
4) simply read each line from (a number in each line) and send it to the output file.
4)简单地从(每行中的一个数字)读取每一行并将其发送到输出文件。
#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;
}
By running the program without any optimization, it runs normally. However, by specifying -O3
, it fails to create the output file. Why???
通过运行程序而不进行任何优化,它可以正常运行。但是,通过指定-O3,它无法创建输出文件。为什么???
$ g++ -o cdf cdf.cpp
cdf.cpp: In function ‘int main(int, char**)’:
cdf.cpp:19: warning: deprecated conversion from string constant to ‘char*’
$ ./cdf in.txt
cdf_in.txt
$ ls cdf*
cdf cdf.cpp cdf_in.txt cdf.py
$ cat cdf_in.txt
10
5
3
2
1
$ rm cdf_in.txt
$ g++ -O3 -o cdf cdf.cpp
cdf.cpp: In function ‘int main(int, char**)’:
cdf.cpp:19: warning: deprecated conversion from string constant to ‘char*’
$ ./cdf in.txt
cdf_in.txt
$ ls cdf*
cdf cdf.cpp cdf.py
Why the fout
doesn't work with -O3
?
为什么fout不能与-O3一起使用?
1 个解决方案
#1
Your strcat(res, o1);
depends on res[0] == '\0'
, which may be true, but isn't guaranteed (res
is an uninitialized local, so its contents aren't known/specified).
你的strcat(res,o1);取决于res [0] =='\ 0',这可能是真的,但不保证(res是未初始化的本地,因此其内容未知/指定)。
Chances are that it's being initialized to zeros when you don't do optimization, but not when you do.
当你不进行优化时,它可能会被初始化为零,但是当你没有进行优化时,它会被初始化为零。
You could fix it by initializing res
, or by using strcpy
instead of strcat
for the first item you want to copy there (but this still leaves possible buffer overrun problems, so see below for better alternatives).
您可以通过初始化res来修复它,或者通过使用strcpy而不是strcat来复制您要复制的第一个项目(但这仍然存在可能的缓冲区溢出问题,因此请参阅下面的更好的替代方案)。
Or, of course, you could write code that's more like C++ instead of C, and use std::string
instead of arrays of char.
或者,当然,您可以编写更像C ++而不是C的代码,并使用std :: string而不是char数组。
std::string fname("cdf_");
fname += argv[1];
std::ofstream fout(fname.c_str()); // just `fout(fname)` with a C++11 compiler
If you really want to write C-like code for some reason, it's probably easier to use sprintf
in this case:
如果你真的想出于某些原因编写类似C的代码,在这种情况下使用sprintf可能更容易:
char res[30];
sprintf(res, "cdf_%35s", argv[1]);
std::ofstream fout(res);
#1
Your strcat(res, o1);
depends on res[0] == '\0'
, which may be true, but isn't guaranteed (res
is an uninitialized local, so its contents aren't known/specified).
你的strcat(res,o1);取决于res [0] =='\ 0',这可能是真的,但不保证(res是未初始化的本地,因此其内容未知/指定)。
Chances are that it's being initialized to zeros when you don't do optimization, but not when you do.
当你不进行优化时,它可能会被初始化为零,但是当你没有进行优化时,它会被初始化为零。
You could fix it by initializing res
, or by using strcpy
instead of strcat
for the first item you want to copy there (but this still leaves possible buffer overrun problems, so see below for better alternatives).
您可以通过初始化res来修复它,或者通过使用strcpy而不是strcat来复制您要复制的第一个项目(但这仍然存在可能的缓冲区溢出问题,因此请参阅下面的更好的替代方案)。
Or, of course, you could write code that's more like C++ instead of C, and use std::string
instead of arrays of char.
或者,当然,您可以编写更像C ++而不是C的代码,并使用std :: string而不是char数组。
std::string fname("cdf_");
fname += argv[1];
std::ofstream fout(fname.c_str()); // just `fout(fname)` with a C++11 compiler
If you really want to write C-like code for some reason, it's probably easier to use sprintf
in this case:
如果你真的想出于某些原因编写类似C的代码,在这种情况下使用sprintf可能更容易:
char res[30];
sprintf(res, "cdf_%35s", argv[1]);
std::ofstream fout(res);