我有一个看起来像这样的文件:
Mike 1200
John 350
Jen 1500
Tara 700
Michelle 2000
Kevin 500
Matt 450
Kim 200
我存储内容的代码:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
const int MAX = 15;
int main() {
// declare variables
string names[MAX];
string tempscore;
float scores[MAX];
fstream infile;
infile.open("winners.txt", ios::in);
int cc = 0;
getline(infile, names[cc], ' ');
infile.ignore( 0, ' ');
infile >> tempscore;
infile.ignore( 1, '\n');
scores[cc] = strtof(tempscore.c_str(), NULL);
cout << "'" << names[cc] << "'" << endl;
cout << "'" << scores[cc] << "'" << endl;
int i = 1;
while (infile) {
getline(infile, names[i], ' ');
infile.ignore( 0, ' ');
infile >> tempscore;
infile.ignore( 1, '\n');
scores[cc] = strtof(tempscore.c_str(), NULL);
cout << "'" << names[i] << "'" << endl;
cout << "'" << scores[i] << "'" << endl;
i++;
}
infile.close();
return 0;
}
大多数名称都存储正确但没有得分。为什么?我做错了什么?
这是我想要实现的最佳方式吗?
答案 0 :(得分:3)
您的代码中存在拼写错误。 scores[cc] = strtof(tempscore.c_str(), NULL);
循环中的scores[i] = strtof(tempscore.c_str(), NULL);
应为while
。
一些附注:
0
while
循环中的数组边界。如果可能,请考虑使用vector
getline
的返回值。如果您希望保持代码不使用stringstream
,请考虑将while
条件更改为while(i < MAX && getline(infile, names[i], ' '))
(以及ofc,删除后续的getline
来电。请注意在i < MAX
之前进行getline
检查非常重要,否则可能会出现细分错误,names[i]
中使用了getline
C++11
,请考虑使用stof
代替strtof
,因为它直接在string
上运行,并且无需为其获取C-str < / LI>
醇>
希望这有帮助!
答案 1 :(得分:2)
对于基于行的文件解析,首先读取该行并将其放入字符串流中,然后直接从该字符串流中读出每个字段,而不将其存储在字符串中并进行转换。
int main() {
const int MAX = 15;
// declare variables
std::string names[MAX];
float scores[MAX];
std::fstream infile;
infile.open("winners.txt", std::ios::in);
int i = 0;
std::string line;
while (getline(infile, line)) {
std::stringstream input(line);
input >> names[i] >> scores[i];
if (input) {
std::cout << "'" << names[i] << "'" << std::endl;
std::cout << "'" << scores[i] << "'" << std::endl;
i++;
if (i >= MAX) break; // protect your array or use a vector or deque
}
}
infile.close();
return 0;
}
答案 2 :(得分:1)
如果您能够使用getline
两次,请执行getline(infile, names[cc], ' ');
和getline(infile, score[cc], ' ');
或者像这样格式化文本文件:
Mike
1200
John
350
Jen
1500
等
在这种情况下,每三行包含得分,由2开始,名称相同但以1开始。计数1,4,7,10等,以及2,5,8,11等。你知道,哪些是名字,哪些是分数。
编辑:它不是主要问题的答案,但可能是一个很好的实施。答案 3 :(得分:1)
如果您使用该文件格式,则可以执行以下操作:
- 阅读
行- 获取您找到的第一个空格字符的位置(因为那是您的分隔符)
- 从该位置拆分字符串。
- 将前半部分存储到字符串数组中,然后存储使用第二个调用的函数atoi(secondHalf.c_str())的输出 一半作为你的得分数组的参数。
醇>
如果您不使用实数,我也会将得分数组更改为int而不是float。
更新: 这是我想告诉你的一个示例代码。我在这里用名字和分数的向量:
int i = 0;
for(i=0; i<line.size(); i++)
{
if(line[i] == ' ') break; //Then we have the position of the space char
}
names.push_back(line.substr(0,i));
scores.push_back(std::string(atoi(line.substr(i))));
答案 4 :(得分:1)
您可以使用C函数从文件中读取格式化的行:
FILE *fp = NULL;
int score = 0;
char name[20];
fp = fopen("winners.txt", "r");
if(!fp)
return -1;
while(tell(fp) != EOF) {
fscanf(fp, "%s %d", name, &score);
printf("Name : %s, Score : %d", name, score);
}
不要忘记#include <cstdio>