Определить байт новой строки из файлового потока - PullRequest
2 голосов
/ 13 марта 2009

Я пытаюсь собрать информацию из текстового файла, который содержит названия организаций (без пробелов) и плавающие целые числа. Я хочу хранить эту информацию в структуре массива.

Проблема, которую я имею до сих пор, заключается в сборе информации. Вот образец текстового файла:

CBA 12,3 4,5 7,5 2,9 4,1

TLS 3,9 1 8,6 12,8 4,9

У меня может быть до 128 разных номеров для каждой организации и до 200 организаций в текстовом файле.

Вот так выглядит моя структура:

struct callCentre
{
char name[256];
float data[20];
};

Моя главная:

int main()
{
callCentre aCentre[10];
getdata(aCentre);
calcdata(aCentre);
printdata(aCentre);
return 0;
}

И функция getdata:

void getdata(callCentre aCentre[])
{
ifstream ins;
char dataset[20];

cout << "Enter the name of the data file: ";
cin >> dataset;

ins.open(dataset);

if(ins.good())
{
    while(ins.good())
    {
        ins >> aCentre[c].name;
        for(int i = 0; i < MAX; i++)
        {
            ins >> aCentre[c].data[i];
            if(ins == '\n')
                break;
        }
        c++;
    }
}
else
{
    cout << "Data files couldnt be found." << endl;
}
ins.close();
}

В своей функции getdata я пытаюсь добиться следующего: сначала сохранить название организации в структуре, а затем прочитать каждый float в массив данных, пока программа не обнаружит байт новой строки. Однако, пока моя проверка на байт новой строки не работает.

Предположим, что переменные c и MAX уже определены.

Как мне правильно поступить?

Ответы [ 4 ]

3 голосов
/ 13 марта 2009

Вам нужно прочитать строки, а затем нарезать их. Следующий фрагмент хакерства иллюстрирует основную идею:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {
    string line;
    while( getline( cin, line ) ) {
        istringstream is( line );
        string cs;
        is >> cs;
        double vals[10];
        int i = 0;
        while( is >> vals[i] ) {
            i++;
        }

        cout << "CS: " << cs;
        for ( int j = 0; j < i; j++ ) {
            cout << " " << vals[j];
        }
        cout << endl;
    }
}
3 голосов
/ 13 марта 2009

Оператор >> обрабатывает пробелы как разделитель, который включает в себя новые строки, поэтому он просто съедает их, а вы их никогда не видите.

2 голосов
/ 13 марта 2009

Я бы прочитал файл, одну строку за другой, и проанализировал каждую строку отдельно для значений:

std::string line;
while (std::getline(ins, line)) {
  std::istringstream sline(line);
  sline >> aCentre[c].name;
  int i = 0;
  while (sline >> aCentre[c].data[i])
    i++;
  c++;
}
2 голосов
/ 13 марта 2009
char byte = ins.peek();

Или

if(ins.peek() == '\n') break;

(Правка): Вы также захотите проверить eof после вашего взгляда (), потому что некоторые файлы могут не иметь завершающей строки.

Я хотел бы отметить, что вы можете рассмотреть возможность использования vector<callCentre> вместо статического массива. Если длина вашего входного файла превышает емкость массива, вы обойдете весь стек.

...