Итак, я пытаюсь написать программу, которая может читать данные из файла. Файл состоит из целых чисел, символов и удвоений. И я должен уметь назначать их для разных переменных для дальнейшего вычисления (это фактически просто часть более крупной программы). Я искал в Интернете (здесь тоже), и я видел разные решения. stringstream, векторы и многое другое. Тот, с которым я получил наибольшее удовольствие, использовал "пропуски" при чтении. Но я не могу читать целые числа правильно.
Я бы предпочел решение, которое требует использования как можно меньше методов (потоков, файлов и т.д.). Но если мне нужно больше, я смогу жить с ним.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace::std;
int main()
{
int j = 0, kill = 0, i;
char initials[10];
int results[10];
double avg;
ifstream read("P1.txt");
if (!read) //test to see if file can be opened.
{
cerr << "Error" << endl;
exit(1);
}
while(kill != 1) //kill = 1 same as eof. Just my weird way of coding.
{
switch (j)
{
case 0: //read the first line of data, which is the chars.
read >> skipws >> initials;
j++;
break;
case 1: //read the second line of data, which is 10 integers and whitespace
for (i=0;i<10;i++)
read >> skipws >> results[i];
j++;
break;
case 2: //read the last line which is a single double.
read >> skipws >> avg;
j++;
break;
case 3: //check for end of file.
if(read.eof() == 0)
kill = 1;
break;
}
}
//the 3 lines below are just writing the contents of the file to the prompt.
//It to check that values are stored correctly for further use.
cout << initials << endl;
cout << results << endl;
cout << avg << endl;
return 0;
}
Я точно знаю, какой у входного файла "P1.txt" будет выглядеть, потому что я создаю его сам в другой части программы. Это выглядит так:
ccs
2 4 5 3 1 4 6 1 1 1
2.8
Эти 3 строки дают мне инициалы игрока, его результаты в 10 играх и его средний балл. Короче говоря, данные одного игрока. В финальной программе мне нужно читать значения, возможно, для 10 игроков.
Я ожидаю, что 3 строки cout в конце покажут это:
ccs
2453146111
2.8
Теперь это насколько я получил. Если я объявляю результаты [10] как char, я могу получить это в моей консоли:
ccs
2453146111ccs
2.8
Если я объявляю это как int, я получаю это
ccs
0x7fff5fbff6c0
2.8
Очевидно, я вижу, что ценности не хранятся должным образом, и что-то не в порядке, но мне нужны другие лица. Я не знаю.
Я знаю, что это грязный способ сделать это, и что это можно сделать в меньшем пространстве, но я новичок в C++, поэтому это имело смысл для меня, и мне было довольно легко найти ошибки, пока Теперь.
Я попытался объяснить это так, как мог. Это мой первый пост здесь, поэтому, пожалуйста, скажите мне, нужна ли вам дополнительная информация.
Заранее спасибо!! Крис.
когда результаты являются int [10], и вы делаете cout << results << endl, он будет печатать адрес памяти массива, который вы должны сделать loop, чтобы напечатать результат [i] на каждой итерации.
for(i=0;i<10;i++){
cout<< result[i];
}
и это даст правильный результат
Я бы предложил следующее, если вы используете C++:
stringstream
sstringstream
stringstream
называется ss
): ss >> c
(с c
вашим персонажем)ss >> i
(с i
вашим целым числом)ss >> d
(с d
ваш двойной)Некоторый код:
string s[3] = {"ccs",
"2 4 5 3 1 4 6 1 1 1",
"2.8"
};
stringstream ss[3];
/*
Open file, get the first line into s[0], second into s[1] and third into s[2]
*/
ss[0] << s[0];
ss[1] << s[1];
ss[2] << s[2];
char c;
int i;
double d;
vector<char> initials;
vector<int> scores;
vector<double> averages;
while (ss[0] >> c) {
cout << c << " ";
initials.push_back(c);
}
cout << endl;
while (ss[1] >> i) {
cout << i << " ";
scores.push_back(i);
}
cout << endl;
while (ss[2] >> d) {
cout << d << " ";
averages.push_back(d);
}
cout << endl;
Эта проблема значительно упрощается благодаря тому, что ваши данные имеют известный формат. Не позволяйте этому идти впустую.
string initials;
vector<int> r(NUM_SCORES);
double avg;
Теперь, чтобы получить данные:
ifstream infile;
infile.open(...);
while(infile >> initials){ // i.e. "while there another player"
for(int i=0; i<r.size(); i++) infile >> r.at(i);
infile >> avg;
}
Работа выполнена.
cout << "Player " << intials << " scored:" << endl;
for(int i=0; i<r.size(); i++) cout << r.at(i);
cout << endl << "giving him an average of " << avg << endl;
int r0,r1,r2,r3,r4,r5,r6,r7,r8,r9
?!? Почему бы не использовать вместо этого std::vector<int>
или std::array<int,10>
? Можно также использовать apprioprate back_inserter
.
infile >> vector.at(counter); counter++;
?
Также, когда вы читаете значение из файла, это не тип данных "int". вы не можете просто вернуть его в массив int и ожидать, что он будет работать, вам, вероятно, понадобится преобразовать его в int, используя что-то вроде std::stoi
int i; my_ifstream >> i;
,
Не заново изобретайте колесо, вы можете использовать Boost :: tokenizer, чтобы токенизировать строку и использовать Lexical_cast для преобразования строк в числа.
Если вы хотите использовать plain c, вы можете использовать strtok для токенизации строки