在使用之前,您将无条件地从 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;
}