Чтение целых и символов из файла в C ++

0

Итак, я пытаюсь написать программу, которая может читать данные из файла. Файл состоит из целых чисел, символов и удвоений. И я должен уметь назначать их для разных переменных для дальнейшего вычисления (это фактически просто часть более крупной программы). Я искал в Интернете (здесь тоже), и я видел разные решения. 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++, поэтому это имело смысл для меня, и мне было довольно легко найти ошибки, пока Теперь.

Я попытался объяснить это так, как мог. Это мой первый пост здесь, поэтому, пожалуйста, скажите мне, нужна ли вам дополнительная информация.

Заранее спасибо!! Крис.

Теги:

5 ответов

1
Лучший ответ

когда результаты являются int [10], и вы делаете cout << results << endl, он будет печатать адрес памяти массива, который вы должны сделать loop, чтобы напечатать результат [i] на каждой итерации.

for(i=0;i<10;i++){
      cout<< result[i]; 
}

и это даст правильный результат

  • 0
    Я могу поклясться, что я попробовал это, и это не сработало. Я думаю, это то, что происходит, когда вы смотрите на один и тот же код слишком долго. Что-то вроде ')' отсутствует xD Большое спасибо. Работает сейчас
1

Я бы предложил следующее, если вы используете C++:

  • Создайте три stringstream s
  • Прочитайте каждую строку в один stringstream
  • Для использования каждой строки (когда ваш stringstream называется ss):
    • ss >> cc вашим персонажем)
    • ss >> ii вашим целым числом)
    • ss >> dd ваш двойной)
  • Поместите значения в вектор, когда на строке может быть задано более одного ввода.

Некоторый код:

    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;
1

Эта проблема значительно упрощается благодаря тому, что ваши данные имеют известный формат. Не позволяйте этому идти впустую.

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;
  • 0
    int r0,r1,r2,r3,r4,r5,r6,r7,r8,r9 ?!? Почему бы не использовать вместо этого std::vector<int> или std::array<int,10> ? Можно также использовать apprioprate back_inserter .
  • 0
    Это, несомненно, будет более кратким. Причины только моего отсутствия опыта с векторами. Если бы цикл while не нуждался в каком-то счетчике, чтобы сделать infile >> vector.at(counter); counter++; ?
Показать ещё 4 комментария
1

Также, когда вы читаете значение из файла, это не тип данных "int". вы не можете просто вернуть его в массив int и ожидать, что он будет работать, вам, вероятно, понадобится преобразовать его в int, используя что-то вроде std::stoi

  • 0
    Мусор, int i; my_ifstream >> i; ,
  • 0
    Просто вернулся, чтобы отредактировать это, открыл старый проект, чтобы проверить мою логику, и кажется, что мой пользовательский класс возвращает все обратно в строки перед возвратом, поэтому я должен конвертировать. Не обращай внимания на мою глупость.
1

Не заново изобретайте колесо, вы можете использовать Boost :: tokenizer, чтобы токенизировать строку и использовать Lexical_cast для преобразования строк в числа.

Если вы хотите использовать plain c, вы можете использовать strtok для токенизации строки

Ещё вопросы

Сообщество Overcoder
Наверх
Меню