The following code, simply
1) takes an input file name from the command line argument, say in.txt
2) append the file name to "cdf_"
3) open a file with new name cdf_in.txt
4) simply read each line from (a number in each line) and send it to the output file.
#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???
$ 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
?
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).
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).
Or, of course, you could write code that's more like C++ instead of C, and use std::string
instead of arrays of 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:
char res[30];
sprintf(res, "cdf_%35s", argv[1]);
std::ofstream fout(res);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.