我试图从一个dat文件中提取一个由int组成的日期以及一个char和float值。
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;
}
}
我需要将第一部分作为时间戳分隔为int。 char'M'或'F'需要是它自己的char,最后一位需要是float。
我不知道如何将它们作为自己的变量。
答案 0 :(得分: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");
答案 1 :(得分: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,再读两个并转换为月份等等。
通过这个定义,您只需将记录的时间戳成员定义为该类型的实例,并仍然使用>>
流提取器读取该对象的实例,就像上面一样。