用户手动输入输入和输出路径C ++

时间:2015-08-17 22:08:21

标签: c++ input

我不知道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());`

感谢大家的帮助!

1 个答案:

答案 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;
    }
}