2014-01-15 9 views
0

Я пытаюсь вытащить из файла данных дату, состоящую из ints, а также значение char и float, которые вместе.C++ istream, читающий несколько типов данных в одной строке

формат Dat файл выглядит следующим образом:

201205171200 M29.65 
201207041900 F30.3 

И так далее.

Я борюсь с разделением этих значений. Вот то, что я до сих пор:

#include <iostream> 
#include <fstream> 
#include <vector> 

using namespace std; 

int main() { 
    int inCount = 0; //This variable will be used to keep track of what record is being read. 
    vector<int> dates; 
    vector<float> temps; 
    // Open and retrieve data from text. 
    ifstream inFile; 
    inFile.open("biodata.dat");//Opening Biodata file to begin going through data 
    if(inFile) 
    { 
     char tempType; 
     while(!inFile.eof()) 
      { 
      if (inFile.eof()) break; 
      inFile >> dates[inCount]; 
      cout << dates[inCount]; 
      inFile >> tempType; 
      inFile >> temps[inCount]; 
         if(tempType == 'F'){ 
        temps[inCount] = (temps[inCount] - static_cast<float>(32)) * (5.0/9.0); 
       } 
      inCount++; 

      } 
    } else { 
     cout << "The file did not load"; 
     return 0; 
    } 

} 

мне нужно отделить первую часть в качестве временной метки в качестве междунар. Символ 'M' или 'F' должен быть его собственным символом, а последний бит должен быть плавающим.

Я понятия не имею, как вытащить их как свои собственные переменные.

+0

ваша линия 'вектор даты;.' должен быть 'вектор даты,', чтобы убедиться, что его достаточно большим, чтобы держать эти цифры – RichardPlunkett

+0

Кроме того, вы не кажется, м. в любом месте вашего вектора. Вы можете читать локальные переменные, а затем использовать 'push_back()' для добавления значений в свои векторы, что бы решить это. – RichardPlunkett

ответ

2

Объявляется три переменными и читать их из файла с прикованным извлечением

ifstream inFile("biodata.dat"); 

std::string date; // since your values are so large 
char mf; 
double d; 

while (inFile >> date >> mf >> d) { 
    // use the vars here 
} 

Вы должны будете использовать что-то достаточно большое, чтобы хранить номера. Вы можете использовать long long, если это достаточно большое, но оно может быть недостаточно большим. Вы можете проверить это с помощью static_assert(std::numeric_limits<long long>::max() <= SOME_MAX_EXPECTED_VALUE, "long longs are too small");

+0

Я не думаю, что 32-битный int будет содержать начальное число. Потому что (unsigned even) int caps составляет 4 миллиарда или около того, а число, которое он показывает, составляет 200 миллиардов плюс. так долго или что-то более подходит для этого. – BWG

+0

@ BWG хороший момент, я не заметил размер. Я переключился на std :: string. Я добавлю примечание, хотя –

1

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

struct record { 
    unsigned long long timestamp; 
    float temp; 

    std::istream &operator>>(std::istream &is, record &r) { 
     char temp; 
     is >> r.timestamp >> temp >> r.temp; 
     if (temp == 'F') { 
      r.temp -= 32.0f; 
      r.temp *= 5.0f/9.0f; 
     } 
     return is;    
    } 
}; 

С этим определено, вы можете читать и вся запись в одной операции:

record r; 

infile >> r; 

Или (как выглядит, как вы, вероятно, хотите здесь) вы можете прочитать весь вектор из них сразу:

std::vector<record> records { 
    std::istream_iterator<record>(infile), 
    std::istream_iterator<record>() 
}; 

вы можете предпочесть разделить штамп времени на отдельные поля когда вы их читаете. Если это так, вы можете определить структуру timestamp и сделать по существу то же самое с ней - определить поля для года, месяца, дня, часа и минуты, затем определить operator>>, чтобы читать каждое поле отдельно (читать четыре символа, преобразовывать их в int int for year, читать еще два и конвертировать в месяц и т. д.

С помощью этого определения вы просто определяете свой элемент временной метки записи как экземпляр этого типа и все еще читаете экземпляр этого объекта с >> потока экстрактор, так же, как выше