我不知道C ++,但我已被指派编辑这段代码:
// Setup path information for output file from environmental variables
char * path = new char[100];
path = getenv("MODEL_MERGE");
char * templatePath = new char[100];
char * outputPath = new char[100];
strcpy(templatePath, path);
strcat(templatePath, "infile location");
strcpy(outputPath, path);
strcat(outputPath,"outfile location");
cout << "temp: " << templatePath << endl;
cout << "out: " << outputPath << endl;
//input output file streams for reading/writing to files
ifstream readFile(templatePath);
ofstream outFile(outputPath);
我的目标是更换&#34; infile location&#34;和&#34; outfile location&#34;,当前指向特定文件。我希望用户能够在从命令提示符运行时输入文件名。很抱歉,如果这只是<<cin
这么简单,但我无法使用,而且我没有这种语言的经验。
知道了!以上所有内容都被替换为:
//User inputs paths
string input;
string output;
cout<<"Input path?"<<endl;
cin>> input;
cout<<"output path?"<<endl;
cin>> output;
//input output file streams for reading/writing to files
ifstream readFile(input.c_str());
ofstream outFile(output.c_str());`
感谢大家的帮助!
答案 0 :(得分:2)
除了将OP指向有用的方向之外,提供给OP的代码还有足够的错误值得快速进行。
首先,在调用getenv时没有测试NULL。如果MODEL_MERGE
不存在,则返回NULL,然后在字符串副本中使用。 BOOM!
其次,new
所有这些数组。动态分配仅作为最后的手段。 new
必须至少使用一个delete
,具体取决于代码的流程,以便在不再需要时返回已分配的内存以供重用。由于似乎不需要动态分配并且已知数组的大小,因此它们应该被定义为char templatePath[100];
。更少的内存管理需要处理,实际上没有泄漏的可能性。
第三点使得第二点过时了。而不是使用char数组,尽可能使用字符串。它们不仅可以处理所有的内存管理,包括根据需要调整大小而不是践踏超出范围,对于您来说,它们还可以执行复制和附加等日常任务,而不用大惊小怪。我将在下面演示这一点。
在许多网站上正确使用cin和cout非常详细,所以我不会在这里讨论它。
另请注意,我已通过明确声明使用的命名空间删除了对using namespace std;
的需求。 Read why using namespace std;
is often a bad idea.
#include <fstream>
#include <iostream>
int main()
{
char * Model_MergePath = getenv("MODEL_MERGE");
if (Model_MergePath != NULL)
{ //MODEL_MERGE is defined
std::string path(Model_MergePath); //replace icky and fault-prone char array
std::string templatePath = path; // copy strings with =
std::string outputPath; // not assigning path here so I can demonstrate
//something else later
std::string inFileLoc; // new throw away variables for user input.
std::string outFileLoc; // could use the same var for both. I didn't for clarity
std::cin >> inFileLoc; // get input
templatePath += inFileLoc; // append to strings with +=
std::cin >> outFileLoc;
outputPath = path + outFileLoc; // concatenate strings with +
// validate paths for correctness and possible intrusion attempts here
// this, I'm afraid, is up to the OP as the security requirements are unknown
std::cout << "temp: " << templatePath << std::endl;
std::cout << "out: " << outputPath << std::endl;
//input output file streams for reading/writing to files
std::ifstream readFile(templatePath);
// older C++ compilers may require a c-style string as the file path
std::ofstream outFile(outputPath.c_str());
// do stuff with readFile and outFile
// remove the deletes that should have corresponded to the replaced `new`s
return 0;
}
else
{ //MODEL_MERGE is NOT defined
std::cerr << "Cannot find environment variable MODEL_MERGE. Exiting." << std::endl;
return -1;
}
}