简体   繁体   English

在C ++中打开多个文件

[英]Opening multiple files in C++

I have this code to open multiple files one at a time that is given at the command line, and then if it cannot open one of the files, it closes all the files and exits. 我有这段代码可以在命令行中一次打开一个文件,然后如果不能打开其中一个文件,则关闭所有文件并退出。

/* Opens an array of files and returns a pointer to the first 
 * element (the first file).
 */
ifstream *OpenFiles(char * const fileNames[], size_t count)
{
    /* If no command line arguments, error and exit */
    if (count == 0) {
        cerr << "Invalid number of arguments.";
        exit(EXIT_FAILURE);
    }
    ifstream *fileObj;
    fileObj = new ifstream[count];

    if (fileObj == NULL) {
        cerr << "Failed to create space for files";
        exit(EXIT_FAILURE);
    }

    /* Opens one file at a time and closes all files if there is an 
     * error opening any file.
     */
    for (int loopCount = 0; loopCount < (int)count; loopCount++) { 
        fileObj[loopCount].open(fileNames[loopCount], ios::out); 
        if (!fileObj[loopCount].is_open()) { 
            cerr << "Failed to open " << fileNames[loopCount] << "\n";
            for (; loopCount >= 0; loopCount--) {
                fileObj[loopCount].close();
                cout << "Closed " << fileNames[loopCount] << "\n";
            }
            delete[] fileObj;
        } 
    }
    return fileObj;
}

I am doing this for homework and my teacher has another checker we have to submit to and gives me these types of warnings: 我这样做是为了做作业,我的老师还有另一个检查器要提交给我,并给我这些类型的警告:

Assign8_1.cpp(44): error 445: (Warning -- Reuse of for loop variable 'loopCount' at 'line 40' could cause chaos)
    return fileObj;
Assign8_1.cpp(51): error 850: (Info -- for loop index variable 'loopCount' whose type category is 'integral' is modified in body of the for loop that began at 'line 40')
    return fileObj;
Assign8_1.cpp(51): error 449: (Warning -- Pointer variable 'fileObj' previously deallocated [Reference: file Assign8_1.cpp: lines 30, 48])
Assign8_1.cpp(30): error 831: (Info -- Reference cited in prior message)
Assign8_1.cpp(48): error 831: (Info -- Reference cited in prior message)
}
Assign8_1.cpp(63): error 818: (Info -- Pointer parameter 'files' (line 55) could be declared as pointing to const)
}

Starting with the first warning, I was wondering why I shouldn't use my loopCount variable twice the way I do in my code. 从第一个警告开始,我想知道为什么我不应该像在代码中那样两次使用loopCount变量。 That was the way I thought it would work, keeping track of which file I am looking at, opening, and closing it appropriately. 这就是我认为它将起作用的方式,跟踪我正在查看的文件,适当地打开和关闭它。

Does anyone know what error 449 means? 有人知道错误449是什么意思吗? Thanks. 谢谢。

You need to exit(EXIT_FAILURE) after you delete[] fileObj in the loop, otherwise you'll simply crash on the next iteration. 在循环中delete[] fileObj之后,您需要exit(EXIT_FAILURE) ,否则,您将在下一次迭代时崩溃。 That may be what warning 449 is telling you. 那可能是警告449告诉您的内容。

Other than that, the code looks fine. 除此之外,代码看起来还不错。 If you want it to compile without those warnings, though, you could turn the inner loop into a standard for-loop which only uses loopCount as a bound. 但是,如果希望它在没有这些警告的情况下进行编译,则可以将内部循环转换为仅使用loopCount作为绑定的标准for循环。 Something like: 就像是:

for (int i = loopCount; i >= 0; i--) {
    fileObj[i].close();
    cout << "Closed " << fileNames[i] << "\n";
}

You absolutely can use your loopCount variable that way, but it'll cause you a bug. 您绝对可以那样使用loopCount变量,但这会导致错误。 At cursory glance, it looks like it will run forever, because you never break out of the outer loop from the inner loop. 粗略地看,它似乎将永远运行,因为您永远不会从内循环中脱离外循环。 You decrement loopCount in the inner loop, and increment it in the outer loop, back and forth, back and forth. 您可以在内循环中递减loopCount,然后在外循环中来回递增。

Though using a loopCounter in an inner loop isn't a violation of the language, it usually indicates something going on that isn't what you really intended. 尽管在内部循环中使用loopCounter并不违反该语言,但通常表明发生的事情并非您真正想要的。

You would be better off using code like this: 使用以下代码会更好:

list<ifstream> files; 

ifstream file("name"); 
if ( file.is_open() ) { 
   files.push_back(file); 
}  

// close files 
for ( list<ifstream>::iterator i = files.begin(); iter++; i != files.end() ) { 
  i->close();   
}

I'd structure the code more like this: 我将代码的结构更像这样:

for all input names
    if (!open file)
        break;

if (number of open files != number of input names) 
    close the files that did open
return (possibly empty) list of files

449: 449:

After you delete the array, you go round and start trying to open files again - if any of the open calls fail you'll be struck in the loop forever. 删除阵列后,您将开始尝试再次尝试打开文件-如果任何打开调用失败,您将永远陷入循环。 You need either a return or a break after deleting the array. 删除数组后,您需要returnbreak

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM