如何通过用户输入打开文件? 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<std::streamsize>::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++的主要内容,如果未能解决你的问题,请参考以下文章