如何通过用户输入打开文件? C++

Posted

技术标签:

【中文标题】如何通过用户输入打开文件? C++【英文标题】:How do you open a file by user input? C++ 【发布时间】:2021-10-01 14:26:48 【问题描述】:

我想通过用户输入打开一个 txt 文件,并在代码运行时显示它,以便我可以修改它。

每次我尝试打开文件时它都没有打开。我需要将文件保存在某个位置还是我的代码有误?

如果有帮助,这就是我的文件的样子:

inventory.txt

我的代码:

const int max_items = 30;
Item items[max_items];
char mainChoice, subChoice;
int num_items = 0;
int parts;
string filename, description;
ifstream fin;

cout << "Enter the name of the inventory file : ";
getline(cin, filename);

filename = filename.substr(0, filename.length() - 1);

fin.open(filename.c_str());

if (fin.is_open())

    while (!fin.eof())
    
        getline(fin, items[num_items].description); 

        items[num_items].description = items[num_items].description.substr(0, items[num_items].description.length() - 1);

        fin >> items[num_items].num_parts; 
        fin.ignore(100, '\n'); 
        num_items++; 
    

    fin.close(); 


else

    cout << "Unable to open file" << endl;

【问题讨论】:

您的文件需要位于执行程序的工作目录下。或者,您可以提供绝对路径(例如:C:\Users\ATSpiro\Desktop\inventory.txt\home\etc\inventory.txt 我把文件保存到了它应该在的地方,我也尝试输入直接路径,但仍然显示文件无法打开。 你为什么使用:filename = filename.substr(0, filename.length() - 1);“文件名”是否包含扩展名? @JaziriRami 很可能是因为 OP 认为 getline() 留下了一个尾随 \r。这是getline(fin) 的可能性,如果文件使用 CRLF 样式的换行符,但此代码在非 Windows 平台上运行。但getline(cin) 肯定不是这种情况,因此应该删除substr() 【参考方案1】:

在使用之前,您将无条件地从 filename 中删除最后一个字符。 std::getline() 不输出终止行的'\n' 字符。我猜你希望在终端上按下 Enter 以生成\r\n 序列,然后std::getline() 输出'\r' 并关闭'\n'。从std::cin 读取时根本不是这种情况,只会生成'\n'std::getline() 不会输出。因此,您需要完全摆脱 substr() 调用,并按原样使用 filename

cout << "Enter the name of the inventory file : ";
getline(cin, filename);

//filename = filename.substr(0, filename.length() - 1);

fin.open(filename.c_str());
...

但是,如果文件使用 CRLF 样式的换行符,并且代码未在 Windows 上运行,则std::getline() 在读取文件时肯定可以输出'\r' 字符。在这种情况下,您确实需要考虑额外的'\r',但它应该有条件地完成,例如:

getline(fin, description);

if (!description.empty() && description.back() == '\r')
    description.pop_back();

items[num_items].description = description;

话虽如此,您的代码还有一些其他问题:

while (!fin.eof()) is bad.

在调用流的ignore() 方法以丢弃指定分隔符之前的所有内容时,不要使用硬编码的长度值。请改用std::numeric_limits&lt;std::streamsize&gt;::max()

如果文件中有超过 30 个项目,您的 items[] 数组就会溢出。当您不知道编译时的项目数时,您应该使用std::vector

鉴于您显示的文本文件,您根本没有正确解析文件的内容。

试试类似的方法:

#include <iostream>
#include <fstream>
#include <string>
//#include <vector>
#include <limits>
using namespace std;

const int max_items = 30;
Item items[max_items];
int num_items = 0;
//vector<Item> items;

cout << "Enter the name of the inventory file : ";

string filename;
getline(cin, filename);

ifstream fin(filename.c_str());
if (fin.is_open())

    // ignore the file header
    fin.ignore(numeric_limits<streamsize>::max(), '\n');
    fin.ignore(numeric_limits<streamsize>::max(), '\n');

    char description[25];

    while (fin.get(description, 25))
    
        size_t len = fin.gcount();
        if (len > 0 && description[len-1] == '\r')
            --len;

        /*
        Item item;
        item.description = string(description, len);
        fin >> item.num_parts;
        items.push_back(item); 
        */

        items[num_items].description = string(description, len);
        fin >> item[num_items].num_parts;
        ++num_items;
        if (num_items == max_items)
            break;

        //

        fin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    

    fin.close(); 

    // use items as needed...

else

    cout << "Unable to open file" << endl;

或者,使用std::getline() 从文件中读取整行,因此您不必在每次迭代时调用ignore()。您可以使用std::istringstream 来解析每一行,例如:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
//#include <vector>
#include <limits>
using namespace std;

const int max_items = 30;
Item items[max_items];
int num_items = 0;
//vector<Item> items;

cout << "Enter the name of the inventory file : ";

string filename;
getline(cin, filename);

ifstream fin(filename.c_str());
if (fin.is_open())

    // ignore the file header
    fin.ignore(numeric_limits<streamsize>::max(), '\n');
    fin.ignore(numeric_limits<streamsize>::max(), '\n');

    string line;
    while (getline(fin, line))
    
        istringstream iss(line);
        char description[25];

        iss.get(description, 25);

        size_t len = iss.gcount();
        if (len > 0 && description[len-1] == '\r')
            --len;

        /*
        Item item;
        item.description = string(description, len);
        iss >> item.num_parts;
        items.push_back(item); 
        */

        items[num_items].description = string(description, len);
        iss >> item[num_items].num_parts;
        ++num_items;
        if (num_items == max_items)
            break;
    

    fin.close(); 

    // use items as needed...

else

    cout << "Unable to open file" << endl;

【讨论】:

以上是关于如何通过用户输入打开文件? C++的主要内容,如果未能解决你的问题,请参考以下文章

C++中cin和cout输入输出流用法简介

C++中cin和cout输入输出流用法简介

如何使用文件填充数组并将其与用户输入 c++ 进行比较

C++进阶教程:如何获取用户输入

当问题在C++中以相反的顺序要求输入时如何显示用户输入字符串[关闭]

从文件中删除单词每次用户输入要删除的单词并将新数组写入新文件。 C++