代码之家  ›  专栏  ›  技术社区  ›  Crystal

在C++中打开多个文件

c++
  •  0
  • Crystal  · 技术社区  · 15 年前

    我有这样的代码,可以一次打开多个文件(在命令行中给出),如果它不能打开其中一个文件,它将关闭所有文件并退出。

    /* 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;
    }
    

    我在做作业,我的老师有另一个检查,我们必须提交给我,并给我这些类型的警告:

    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)
    }
    

    从第一个警告开始,我想知道为什么我不应该像在代码中那样使用loopcount变量两次。这就是我认为它可以工作的方式,跟踪我正在查看的文件,适当地打开和关闭它。

    有人知道错误449是什么意思吗?谢谢。

    4 回复  |  直到 15 年前
        1
  •  4
  •   Michael Myers KitsuneYMG    15 年前

    你需要 exit(EXIT_FAILURE) 在你之后 delete[] fileObj 在循环中,否则您将在下一个迭代中崩溃。这可能是449号警告告诉你的。

    除此之外,代码看起来还不错。但是,如果希望它在编译时不带这些警告,可以将内部循环转换为仅使用 loopCount 作为约束。比如:

    for (int i = loopCount; i >= 0; i--) {
        fileObj[i].close();
        cout << "Closed " << fileNames[i] << "\n";
    }
    
        2
  •  2
  •   Chris K    15 年前

    当然可以这样使用loopcount变量,但这会导致错误。粗略地看一眼,它看起来会永远运行,因为你永远不会从内部循环中脱离外部循环。您在内部循环中减少循环计数,在外部循环中增加循环计数,前后、前后。

    虽然在内部循环中使用循环计数器并不违反语言,但它通常表示正在发生的事情并不是您真正想要的。

    您最好使用这样的代码:

    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();   
    }
    
        3
  •  1
  •   Jerry Coffin    15 年前

    我会像这样构造代码:

    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
    
        4
  •  0
  •   Douglas Leeder    15 年前

    449:

    删除数组后,您会进行循环并再次尝试打开文件-如果任何打开的调用失败,您将永远在循环中受到攻击。 你需要一个 return 或一个 break 删除数组后。