如何从 C++ 文件的特定行中提取数字(浮点数)?
How to extract a number (float) from a specific line of a file in C++?
我是一名 C++ 初学者,正在尝试创建一个程序来跟踪每个服务员在酒吧提供的产品。其中一部分是从文本文件中读取价格。
每行是一种特定产品的价格。
用户应该键入产品 "code",这实际上是已提供产品的行(所有这一切都将处于循环状态,因为将提供许多产品)。
当用户输入数字时,比方说 5,我怎样才能从文本的第 5 行中获取价格?
也许有一种方法可以在程序启动时将文件导入数组,但我不知道该怎么做。
更新:
我终于修复了代码错误,但我对我的程序真的很不满意。即使是我,当它询问 Y/N 特价时,我只是输入特价,它解释为 "NO"。此外,我现在希望它跟踪每个服务员赚取的钱数,并且每个服务员在文本文件中都有一个与其他服务员相似的名字(例如,第一个服务员的名字在 waiters.txt 的第一行并且去on....) 但根据当天的情况,只会有 4-5 名服务员。如何在不从头开始的情况下扩展程序?
我自己解决了。要从文件中获取行,请使用此
char product_names[101][15];
fstream file("prices.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_prices[i];
}
fstream file2("names.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_names[i];
}
这是整个程序的最终代码,欢迎对可能的改进提出意见。
#include <iostream>
#include<windows.h>
#include<iostream>
#include<fstream>
#include<iomanip>
#include <string>
using namespace std;
int main()
{
float sum[9]={0,0,0,0,0,0,0,0,0};
float product_prices[101];
int code;
float total;
char waiter_name[9][15];
float price;
int wc;
cout <<"How many waiters are there? \n";
int w; // Maximum 9 waiters
cin >> w;
for (int i=1; i<=w; ++i)
{cin >>waiter_name[i];}
string a;
char product_names[101][15];
fstream file("prices.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_prices[i];
}
fstream file2("names.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_names[i];
}
ST:
while (true)
{ cout << "Please give product code or type -1 when you're done. \n";
cin >> code;
if (code==-1) break;
cout << "Please give the waiter's code. \n";
cin >> wc;
price=product_prices[code];
cout <<"Default price is " << price << " . Type Y/N if you want to make a special price or A to chose another product or waiter\n";
cin >> a;
if (a=="Y"||a=="y") { cin >> price; }
else if (a=="A" || a=="a") {goto ST;}
sum[wc]+=price;
cout << waiter_name[wc] <<" : " <<sum[wc] <<"\n";
}
for (int i=1; i<=w; ++i)
{
cout << waiter_name[i] <<" : " <<sum[i] <<"\n";
total+= sum[i];
}
return 0;
}
还有@ArchbishopOfBanterbury,我没想到你会为此编写整个程序。但是,我无法理解缓冲区的作用,我只有一个 product_prices.txt 和一个 product_names.txt 并且产品代码是行号。至于未经测试的代码,远远超出了我的知识水平,我什至不知道如何使用地图。不过还是谢谢你。
产品价格放在文件中,一个在另一个下面。名称也以这种方式存储。例如,第一个产品的名称在 product_names.txt 的第一行,它的价格在 product_prices.txt 的第一行。
以下代码提供了执行此操作的粗略概述,其中输入文件的每一行都保存到 std::map
,其中映射的键对应于输入文件的行和value 是该行文件的价格。然后可以使用 std::map
的 find
方法快速访问与文件行关联的价格,其中 returns 迭代器指向在地图中搜索的位置。
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
int main(void) {
std::map<unsigned int, double> line_price_map;
// give file name (and absolute path if not in current directory) here
const char* file_path = "";
std::ifstream file(file_path);
std::string buffer = "";
unsigned int count = 0;
while (getline(file, buffer)) {
// convert std::string buffer to a double
double price = atof(buffer.c_str());
line_price_map.insert(std::make_pair(++count, price));
}
// search for a specific line:
double search_price = line_price_map.find(5)->second;
}
此代码当然不完整,需要根据您的具体要求进行更改。
至于存储产品名称和产品代码,我将使用以下格式包含这些数据的文本文件:
product_code product_name product_price
... ... ...
这样您就可以像以前一样使用 getline
逐行读取内容,解析输入以获取产品代码、名称和价格,然后将这些值存储在 std::map
结构如下:
std::map<unsigned int, std::pair<std::string, double>> product_map;
其中 unsigned int
类型的键表示 product_code(也可以是 std::string
)和 std::pair<std::string, double>
(与键关联的映射的值) 给出 product_name(如 std::string
)和产品价格(如 double
)。
这是我刚刚编写的一些(未经测试的)代码,以使其更清晰:
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
/**
* Parses std::string _buffer line input, assigning correct data
* to code, name and price params.
*/
void parse_input(unsigned int& _prod_code, std::string& _prod_name,
double& _prod_price, const std::string& _buffer) {
size_t count1 = 0;
// find first tab character
while (_buffer.at(count1) != '\t') {
++count1;
}
// set product code to substring of _buffer from beginning
// to first tab, converted to integral type
_prod_code = atoi(_buffer.substr(0, count1).c_str());
size_t count2 = count1 + 1;
// find second tab character
while (_buffer.at(count2) != '\t') {
++count2;
}
// set product code to substring of _buffer from end of first tab
// to next tab occurrence
_prod_name = _buffer.substr(count1 + 1, count2);
size_t count3 = count2 + 1;
while (_buffer.at(count3) != '\t') {
++count3;
}
// set product price to last entry of tabbed columns of input
_prod_price = atof(_buffer.substr(count2 + 1, count3).c_str());
}
int main(void) {
std::map<unsigned int, std::pair<std::string, double>> product_map;
const char* pfile_path = "product_data.txt";
std::ifstream product_file(pfile_path);
std::string buffer = "";
// get file contents line by line
while (getline(product_file, buffer)) {
unsigned int product_code;
std::string product_name;
double product_price;
// call parse_input with product data vars and buffer
parse_input(product_code, produce_name, product_price, buffer);
// insert data to product_map
product_map.insert(std::make_pair(product_code,
std::make_pair(product_name, product_price)));
}
}
这使用了一个非常粗糙的解析函数,但它应该工作得很好 - 假设产品数据在文件中以制表符分隔,如上所示。
我是一名 C++ 初学者,正在尝试创建一个程序来跟踪每个服务员在酒吧提供的产品。其中一部分是从文本文件中读取价格。
每行是一种特定产品的价格。
用户应该键入产品 "code",这实际上是已提供产品的行(所有这一切都将处于循环状态,因为将提供许多产品)。
当用户输入数字时,比方说 5,我怎样才能从文本的第 5 行中获取价格?
也许有一种方法可以在程序启动时将文件导入数组,但我不知道该怎么做。
更新: 我终于修复了代码错误,但我对我的程序真的很不满意。即使是我,当它询问 Y/N 特价时,我只是输入特价,它解释为 "NO"。此外,我现在希望它跟踪每个服务员赚取的钱数,并且每个服务员在文本文件中都有一个与其他服务员相似的名字(例如,第一个服务员的名字在 waiters.txt 的第一行并且去on....) 但根据当天的情况,只会有 4-5 名服务员。如何在不从头开始的情况下扩展程序?
我自己解决了。要从文件中获取行,请使用此
char product_names[101][15];
fstream file("prices.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_prices[i];
}
fstream file2("names.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_names[i];
}
这是整个程序的最终代码,欢迎对可能的改进提出意见。
#include <iostream>
#include<windows.h>
#include<iostream>
#include<fstream>
#include<iomanip>
#include <string>
using namespace std;
int main()
{
float sum[9]={0,0,0,0,0,0,0,0,0};
float product_prices[101];
int code;
float total;
char waiter_name[9][15];
float price;
int wc;
cout <<"How many waiters are there? \n";
int w; // Maximum 9 waiters
cin >> w;
for (int i=1; i<=w; ++i)
{cin >>waiter_name[i];}
string a;
char product_names[101][15];
fstream file("prices.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_prices[i];
}
fstream file2("names.txt");
for(int i = 1; i <= 100; ++i)
{
file >> product_names[i];
}
ST:
while (true)
{ cout << "Please give product code or type -1 when you're done. \n";
cin >> code;
if (code==-1) break;
cout << "Please give the waiter's code. \n";
cin >> wc;
price=product_prices[code];
cout <<"Default price is " << price << " . Type Y/N if you want to make a special price or A to chose another product or waiter\n";
cin >> a;
if (a=="Y"||a=="y") { cin >> price; }
else if (a=="A" || a=="a") {goto ST;}
sum[wc]+=price;
cout << waiter_name[wc] <<" : " <<sum[wc] <<"\n";
}
for (int i=1; i<=w; ++i)
{
cout << waiter_name[i] <<" : " <<sum[i] <<"\n";
total+= sum[i];
}
return 0;
}
还有@ArchbishopOfBanterbury,我没想到你会为此编写整个程序。但是,我无法理解缓冲区的作用,我只有一个 product_prices.txt 和一个 product_names.txt 并且产品代码是行号。至于未经测试的代码,远远超出了我的知识水平,我什至不知道如何使用地图。不过还是谢谢你。
产品价格放在文件中,一个在另一个下面。名称也以这种方式存储。例如,第一个产品的名称在 product_names.txt 的第一行,它的价格在 product_prices.txt 的第一行。
以下代码提供了执行此操作的粗略概述,其中输入文件的每一行都保存到 std::map
,其中映射的键对应于输入文件的行和value 是该行文件的价格。然后可以使用 std::map
的 find
方法快速访问与文件行关联的价格,其中 returns 迭代器指向在地图中搜索的位置。
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
int main(void) {
std::map<unsigned int, double> line_price_map;
// give file name (and absolute path if not in current directory) here
const char* file_path = "";
std::ifstream file(file_path);
std::string buffer = "";
unsigned int count = 0;
while (getline(file, buffer)) {
// convert std::string buffer to a double
double price = atof(buffer.c_str());
line_price_map.insert(std::make_pair(++count, price));
}
// search for a specific line:
double search_price = line_price_map.find(5)->second;
}
此代码当然不完整,需要根据您的具体要求进行更改。
至于存储产品名称和产品代码,我将使用以下格式包含这些数据的文本文件:
product_code product_name product_price
... ... ...
这样您就可以像以前一样使用 getline
逐行读取内容,解析输入以获取产品代码、名称和价格,然后将这些值存储在 std::map
结构如下:
std::map<unsigned int, std::pair<std::string, double>> product_map;
其中 unsigned int
类型的键表示 product_code(也可以是 std::string
)和 std::pair<std::string, double>
(与键关联的映射的值) 给出 product_name(如 std::string
)和产品价格(如 double
)。
这是我刚刚编写的一些(未经测试的)代码,以使其更清晰:
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <utility>
/**
* Parses std::string _buffer line input, assigning correct data
* to code, name and price params.
*/
void parse_input(unsigned int& _prod_code, std::string& _prod_name,
double& _prod_price, const std::string& _buffer) {
size_t count1 = 0;
// find first tab character
while (_buffer.at(count1) != '\t') {
++count1;
}
// set product code to substring of _buffer from beginning
// to first tab, converted to integral type
_prod_code = atoi(_buffer.substr(0, count1).c_str());
size_t count2 = count1 + 1;
// find second tab character
while (_buffer.at(count2) != '\t') {
++count2;
}
// set product code to substring of _buffer from end of first tab
// to next tab occurrence
_prod_name = _buffer.substr(count1 + 1, count2);
size_t count3 = count2 + 1;
while (_buffer.at(count3) != '\t') {
++count3;
}
// set product price to last entry of tabbed columns of input
_prod_price = atof(_buffer.substr(count2 + 1, count3).c_str());
}
int main(void) {
std::map<unsigned int, std::pair<std::string, double>> product_map;
const char* pfile_path = "product_data.txt";
std::ifstream product_file(pfile_path);
std::string buffer = "";
// get file contents line by line
while (getline(product_file, buffer)) {
unsigned int product_code;
std::string product_name;
double product_price;
// call parse_input with product data vars and buffer
parse_input(product_code, produce_name, product_price, buffer);
// insert data to product_map
product_map.insert(std::make_pair(product_code,
std::make_pair(product_name, product_price)));
}
}
这使用了一个非常粗糙的解析函数,但它应该工作得很好 - 假设产品数据在文件中以制表符分隔,如上所示。