C++:从文件中读取并显示单个项目
C++: Reading in from a file and displaying individual items
所以我有一个 .txt 文件,我应该从中读取信息并以简洁的方式显示 table。这是 .txt 文件内容的片段
格式为
农场名称、物品数量、物品、价格、总价
Collins Farm, 43900 tomatoes 0.67 29413
Bart Smith Farms, 34910 cassavas 0.99 34560.9
Allen Farms, 117 coconuts 0.54 63.18
等...
它应该在控制台中打印为
Collins Farm (some spaces here) 43900 items contributed totaling 413.00
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int addLine(int);
int main()
{
using std::ifstream;
ifstream myFile;
myFile.open("ASSGN6-B.txt");
string farmName;
int itemCount;
string itemName;
double itemPrice;
double totalPrice;
if (!myFile)
{
cout << "File open failed!" << endl;
}
else
{
cout << "\t\t\t=========================================================" << endl;
cout << "\t\t\t= FARMER'S MARKET INVENTORY =" << endl;
cout << "\t\t\t=========================================================" << endl;
while (myFile.good())
{
getline (myFile, farmName);
getline (myFile, itemName);
myFile >> itemName >> itemPrice >> totalPrice;
cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << endl;
}
}
myFile.close();
return 0;
}
这就是我一直在弄乱的东西,试图弄清楚这个输入的东西是如何工作的。我想我真正不明白的是它应该如何知道哪个项目是哪个。我以前认为它只是一次只读一行,但必须有一种方法可以将同一行上的项目分开并在控制台中单独打印它们。
此外,一些农场名称在 .txt 文件中出现了两次,如果重复,我应该将它们的数据合并到一行中。也将不胜感激。
谢谢。
第一条建议:
不要使用
while (myFile.good()) { ... }
您需要确保您希望读取的数据确实读取成功。
请参阅 Why is iostream::eof inside a loop condition considered wrong? 了解原因。
来到其他问题...
行
getline (myFile, farmName);
将整行读到 farmName
。那不是你想要的。您想要阅读逗号 (,
) 字符之前的所有内容。 std::getline
有这样的选项。使用
getline (myFile, farmName, ',');
不清楚您希望通过
完成什么
getline (myFile, itemName);
可以删除该行。
看样例数据,只需要
myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
读取其余数据。
但是,在您阅读它们之后,请务必忽略该行中的所有内容。您可以为此使用 istream::ignore
。
这是我的建议。
while ( getline(myFile, farmName, ',') &&
(myFile >> itemCount >> itemName >> itemPrice >> totalPrice) )
{
cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << endl;
// Ignore rest of the line
myFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
确保添加
#include <limits>
能够使用std::numeric_limits
。
我认为你应该尝试做更多的研究来理解 c++ 中的文件操作,但我注意到你的代码有一些问题:
getline(myFile, farmName);
此行将读取它正在读取的文件的整行并将其存储到 farmName 中。它基本上读取该行,直到找到行尾字符。我认为您的意图是让该行一直读到农场名称的逗号,因此您可以使用:
getline(myFile, farmName, ',');
第三个参数是一个可选的定界字符,它告诉 getline 要查找的字符以停止读取。
我注意到的下一行是:
getline(myFile, itemName);
myFile >> itemName >> itemPrice >> totalPrice;
为什么要将数据读入 itemName 两次?我认为你的意思是通过你的文件格式的外观先读入 itemCount 在 itemName 之前,因此你应该删除上面显示的第一行并且只有:
myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
就添加到现有数据而言,如果农场名称出现不止一次,您当前的代码将在打印后覆盖每一行的数据并继续 while 循环的下一次迭代。因此,您必须重新设计代码以保存农场的先前值并检查农场是否多次出现并确定从那里做什么。
可以使用 regex:
std::string line;
std::regex r{R"(([^,]*), ?([^ ]*) ([^ ]*) ([^ ]*) (\d*.?\d*))"};
std::smatch m;
while(getline(myFile, line)){
std::regex_match(line, m, r);
std::string farmName { m[1] };
int itemCount {std::stoi(m[2])};
std::string itemName { m[3] };
double itemPrice {std::stod(m[4])};
double totalPrice {std::stod(m[5])};
std::cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << std::endl;
}
所以我有一个 .txt 文件,我应该从中读取信息并以简洁的方式显示 table。这是 .txt 文件内容的片段 格式为
农场名称、物品数量、物品、价格、总价
Collins Farm, 43900 tomatoes 0.67 29413
Bart Smith Farms, 34910 cassavas 0.99 34560.9
Allen Farms, 117 coconuts 0.54 63.18
等...
它应该在控制台中打印为
Collins Farm (some spaces here) 43900 items contributed totaling 413.00
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int addLine(int);
int main()
{
using std::ifstream;
ifstream myFile;
myFile.open("ASSGN6-B.txt");
string farmName;
int itemCount;
string itemName;
double itemPrice;
double totalPrice;
if (!myFile)
{
cout << "File open failed!" << endl;
}
else
{
cout << "\t\t\t=========================================================" << endl;
cout << "\t\t\t= FARMER'S MARKET INVENTORY =" << endl;
cout << "\t\t\t=========================================================" << endl;
while (myFile.good())
{
getline (myFile, farmName);
getline (myFile, itemName);
myFile >> itemName >> itemPrice >> totalPrice;
cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << endl;
}
}
myFile.close();
return 0;
}
这就是我一直在弄乱的东西,试图弄清楚这个输入的东西是如何工作的。我想我真正不明白的是它应该如何知道哪个项目是哪个。我以前认为它只是一次只读一行,但必须有一种方法可以将同一行上的项目分开并在控制台中单独打印它们。
此外,一些农场名称在 .txt 文件中出现了两次,如果重复,我应该将它们的数据合并到一行中。也将不胜感激。
谢谢。
第一条建议:
不要使用
while (myFile.good()) { ... }
您需要确保您希望读取的数据确实读取成功。
请参阅 Why is iostream::eof inside a loop condition considered wrong? 了解原因。
来到其他问题...
行
getline (myFile, farmName);
将整行读到 farmName
。那不是你想要的。您想要阅读逗号 (,
) 字符之前的所有内容。 std::getline
有这样的选项。使用
getline (myFile, farmName, ',');
不清楚您希望通过
完成什么 getline (myFile, itemName);
可以删除该行。
看样例数据,只需要
myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
读取其余数据。
但是,在您阅读它们之后,请务必忽略该行中的所有内容。您可以为此使用 istream::ignore
。
这是我的建议。
while ( getline(myFile, farmName, ',') &&
(myFile >> itemCount >> itemName >> itemPrice >> totalPrice) )
{
cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << endl;
// Ignore rest of the line
myFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
确保添加
#include <limits>
能够使用std::numeric_limits
。
我认为你应该尝试做更多的研究来理解 c++ 中的文件操作,但我注意到你的代码有一些问题:
getline(myFile, farmName);
此行将读取它正在读取的文件的整行并将其存储到 farmName 中。它基本上读取该行,直到找到行尾字符。我认为您的意图是让该行一直读到农场名称的逗号,因此您可以使用:
getline(myFile, farmName, ',');
第三个参数是一个可选的定界字符,它告诉 getline 要查找的字符以停止读取。
我注意到的下一行是:
getline(myFile, itemName);
myFile >> itemName >> itemPrice >> totalPrice;
为什么要将数据读入 itemName 两次?我认为你的意思是通过你的文件格式的外观先读入 itemCount 在 itemName 之前,因此你应该删除上面显示的第一行并且只有:
myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
就添加到现有数据而言,如果农场名称出现不止一次,您当前的代码将在打印后覆盖每一行的数据并继续 while 循环的下一次迭代。因此,您必须重新设计代码以保存农场的先前值并检查农场是否多次出现并确定从那里做什么。
可以使用 regex:
std::string line;
std::regex r{R"(([^,]*), ?([^ ]*) ([^ ]*) ([^ ]*) (\d*.?\d*))"};
std::smatch m;
while(getline(myFile, line)){
std::regex_match(line, m, r);
std::string farmName { m[1] };
int itemCount {std::stoi(m[2])};
std::string itemName { m[3] };
double itemPrice {std::stod(m[4])};
double totalPrice {std::stod(m[5])};
std::cout << farmName << " " << itemCount << " items contributed totaling $" << totalPrice << std::endl;
}