readFile 函数不适用于具有不同参数的第二次迭代 - C++

readFile function not working on second iteration with different argument - c++

我为我正在进行的项目编写了一个 readFile 函数。我调用它一次,加载一个文件并读取它的内容 - 工作正常

然而,当我第二次尝试加载它时,试图更改文件名 - 它加载它,将它保存到我在不同函数中访问的静态字符串 'path' - 但随后该函数不打印数据

问题是,如何更改文件名,并在第二次迭代时成功读入?让我难过的部分是它只工作一次,而不是两次

我试过使用 cin.ignore(); cin.clear(); cin.sync() 在 fileName 函数的第二次迭代中 - 但其中 none 允许成功读取单独的文件。

最小可重现示例:

#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <iomanip>
#include <iostream>

using namespace std;

static string path;
string opt;
void readFile();
int fileName();

void menu() { // put in while loop - while True
    cout << "----------------------" << endl;
    cout << "R(ead) -" << "Read File" << endl;
    cout << "F(ile) -" << "Set Filename" << endl;
    cout << "\nPlease select from the above options" << endl;
    cin >> opt;
    cout << "\nInput entered: " << opt << endl;
    if (opt == "R") {
        readFile();
    }
    if (opt == "F") {
        fileName();
    }
}

void readFile() { // doing this twice
    ifstream readFile;
    readFile.open(path);
    if (!readFile.is_open()) {
        cout << "Could not read file" << endl;
    }
    string str;

    int i = 0;
    while (getline(readFile, str))
    {
        if (str[0] != '/')
        {
            cout << "DEBUG: Line is - " << str << endl;
        }
    }
    readFile.clear();
    readFile.close();
    menu();
}

int fileName() {
    cout << "File path: ";
    if (path != "") {
        cin.ignore();
        cin.clear();
        cin.sync();
    }
    getline(cin, path);
    ifstream file(path.c_str());
    if (!file) {
        cout << "Error while opening the file" << endl;
        return 1;
    }
    cout << "(File loaded)" << endl;
    cout << "Path contains: " << path << endl;
    file.clear();
    file.close();
    menu();
}

int main()
{
    fileName();
}

示例文本,保存为 txt 文件并使用路径读取: Data1.txt

// standard test file
123,Frodo inc,2006, lyons,"1,021,000.16",0.0,
U2123,Sam Inc,2006, lyons,"21,600.00",13.10,123
A721,Merry Inc,2604, Kingston,"21,600.10",103.00,
U2122,Pippin Inc,2612, reid,"21,600.00",0
U1123,Huckelberry corp,2612, Turner,"21,600.00",13.10,

Data2.txt

7101003,Mike,23 boinig road,2615,48000,12000,0
7201003,Jane Philips,29 boinig cresent,2616,47000,12000,0
7301003,Philip Jane,23 bong road,2615,49000,000,0
7401004,Peta,23 bong bong road,2615,148000,19000,0
7101205,Abdulla,23 Station st,2615,80000,21000,0

问题来自读入一个,并在第一个执行后尝试读入另一个。

  1. 输入文件名
  2. 点击读取文件
  3. Return 到菜单,点击设置文件名
  4. 改为Data2.txt
  5. 再次读取文件。不工作

我的导师告诉我“这不是函数在 c++ 中的工作方式”但没有进一步详细说明,也无法联系。

一般情况下,不要使用全局变量。路径变量应作为参数传递,而不是作为全局变量在函数调用之间更改,因为这会导致许多副作用,并且是无数错误的根源。请参阅以下重构:

void menu() { // put in while loop - while True
while(true)
{
    //Keep this as a local variable!
    std::string opt;
    std::string filename;
    cout << "----------------------\n";
    cout << "R(ead) -" << "Read File\n";
    cout << "F(ile) -" << "Set Filename\n";
    cout << "\nPlease select from the above options\n";
    cin >> opt;
    cout << "\nInput entered: " << opt << '\n';
    if (opt == "R") {
        readFile(filename);
    }
    if (opt == "F") {
        filename = getFileName();
    }
}
}

void readFile(const std::string & filename) { 
    ifstream readFile;
    readFile.open(filename);
    if (!readFile.is_open()) {
        cout << "Could not read file " << filename << '\n';
    }
    string str;

    int i = 0;
    while (getline(readFile, str))
    {
        if (str[0] != '/')
        {
            cout << "DEBUG: Line is - " << str << '\n';
        }
    }
    readFile.close();
    //just return to get back to menu
    return;
}

std::string getFileName() {
    cout << "File path: ";
    std::string path;
    getline(cin, path);
    ifstream file(path.c_str());
    if (!file) {
        cout << "Error while opening the file" << '\n';
        //Instead of returning an error code use an exception preferably
    }
    cout << "(File loaded)" << '\n';
    cout << "Path contains: " << path << '\n';
    file.close();
    return path;
}

其他说明: 理想情况下,只在一个函数中输入输出,而不是全部三个,因为它会混淆每个函数的确切职责。

如果你想要一些东西来保存文件并打印内容,你可以使用 class。

检查文件是否可以打开两次,没有任何理由这样做只是将责任委托给一个函数。

关于 C++ 的最好的事情之一是对象和基元的 RAII 和确定性生命周期——使用它!!不要使用全局变量让所有东西都长寿 - 使用智能参数和 return 值代替。