如何从 CSV 文件中的特定列中读取值以执行计算 - C++
How to read in values from specific columns in a CSV file to perform calculations - C++
所以我试图将 csv 文件中的一些数据读入我的程序,但我只想要一些特定的列。我知道网上有很多关于此的资料,但我似乎无法满足我的要求。
首先,我创建了一个包含日期和时间(class 对象)和文件中的速度值的结构,并将其存储在我自己制作的 Vector 模板 class 中。我的主程序现在可以正确处理这样的测试文件:
31/12/2013 11:45,55.6
日期和时间一起读,然后分开,没问题。现在这是实际的文件:
WAST,DP,Dta,Dts,EV,QFE,QFF,QNH,RF,RH,S,SR,ST1,ST2,ST3,ST4,Sx,T
31/03/2016 09:00,14.6,175,17,0,1013.4,1016.9,1017,0,68.2,6,512,22.7,24.1,25.5,26.1,8,20.74
31/03/2016 09:10,14.6,194,22,0.1,1013.4,1016.9,1017,0,67.2,5,565,22.7,24.1,25.5,26.1,8,20.97
31/03/2016 09:20,14.8,198,30,0.1,1013.4,1016.9,1017,0,68.2,5,574,22.7,24,25.5,26.1,8,20.92
我想做的是从 WAST 列中提取详细信息,即日期和时间,然后从 S 列中提取速度。我对如何做到这一点有一个通用的想法,即:将整个第一行提取到一个字符串中,并忽略除 WAST 和 S 或类似内容之外的所有内容。但即便如此,我应该如何只在我想要的列下获得每个值?请帮忙。
Main.cpp:
#include <iostream>
#include <string>
#include <fstream>
#include "Date.h"
#include "Time.h"
#include "Vector.h"
using namespace std;
typedef struct {
Date d;
Time t;
float speed;
}WindLogType;
int main()
{
Date dTest;
Time tTest;
float speedtest = 52.5;
Vector<WindLogType> windlog;
ifstream infile("testinput2.csv");
if(!infile){
cout << "File not found.";
return -1;
};
WindLogType windlog2;
//int i = 0;
while(!infile.eof()){
infile >> windlog2.d >> windlog2.t >> windlog2.speed;
windlog.add(windlog2);
}
for(int i = 0; i < windlog.size(); i++){
cout << windlog[i].d << " " << windlog[i].t << " Speed: " << windlog[i].speed << endl;
}
infile.close();
return 0;
}
您在这里可以做的是为您的结构 WindLogType
编写一个流提取运算符,用于一次一行地读取文件,从该行中提取您需要的信息并填充结构。
std::getline
不仅可以用来读取整行,还可以使用定界符标记字符串。
您可以尝试使用一些评论来解释以下内容:
#include <fstream>
#include <string>
#include <sstream>
using Date = std::string;
using Time = std::string;
typedef struct {
Date d;
Time t;
float speed;
} WindLogType;
std::istream& operator >> (std::istream& is, WindLogType& sl) {
// Read a complete line
std::string line;
if (std::getline(is, line)) {
auto iss = std::istringstream{line};
// Read date from line (up to space)
std::getline(iss, sl.d, ' ');
// Read time (up to ',')
std::getline(iss, sl.t, ',');
std::string speed;
// Read speed (up to next comma)
std::getline(iss, speed, ',');
sl.speed = std::stof(speed);
}
return is;
}
int main()
{
std::ifstream infile("testinput2.csv");
if (!infile) {
std::cout << "File not found.";
return -1;
};
Vector<WindLogType> windlog;
std::string str;
std::getline(infile, str); // skip the first line
WindLogType windlog2;
while (infile >> windlog2) {
windlog.add(windlog2);
}
return 0;
}
流提取运算符 (>>
) 从文件中读取一行。使用该行,它从中创建一个 std::istringstream 对象,然后使用 std::getline
.
提取相关信息
我不知道你的 Date
和 Time
类型是如何定义的。我刚刚将它们别名为 std::string
。您必须自己对字符串进行处理。
希望这有用。
编辑:
你不能while(infile >> windlog2.d >> windlog2.t >> windlog2.speed)
的原因是>>
读到白色space/newline。您的数据有点复杂:它是逗号分隔的,并且您已经解析了日期和时间字段。上述方法的好处是它允许您将数据直接流式传输到 WindLog
结构中。
如果您真的不想为您的类型使用流提取运算符,您可以使用相同的代码。它将是这样的:
std::string line;
std::getline(infile, line); // skip the first line
while (std::getline(infile, line)) {
WindLogType sl;
auto iss = std::istringstream{ line };
// Read date from line (up to space)
std::getline(iss, sl.d, ' ');
...
}
我个人更喜欢为一种类型使用流提取运算符,因为它将所有读取操作封装在一个函数中,但如果您想进行一些其他处理,则可以采用第二种方法。
所以我试图将 csv 文件中的一些数据读入我的程序,但我只想要一些特定的列。我知道网上有很多关于此的资料,但我似乎无法满足我的要求。
首先,我创建了一个包含日期和时间(class 对象)和文件中的速度值的结构,并将其存储在我自己制作的 Vector 模板 class 中。我的主程序现在可以正确处理这样的测试文件:
31/12/2013 11:45,55.6
日期和时间一起读,然后分开,没问题。现在这是实际的文件:
WAST,DP,Dta,Dts,EV,QFE,QFF,QNH,RF,RH,S,SR,ST1,ST2,ST3,ST4,Sx,T
31/03/2016 09:00,14.6,175,17,0,1013.4,1016.9,1017,0,68.2,6,512,22.7,24.1,25.5,26.1,8,20.74
31/03/2016 09:10,14.6,194,22,0.1,1013.4,1016.9,1017,0,67.2,5,565,22.7,24.1,25.5,26.1,8,20.97
31/03/2016 09:20,14.8,198,30,0.1,1013.4,1016.9,1017,0,68.2,5,574,22.7,24,25.5,26.1,8,20.92
我想做的是从 WAST 列中提取详细信息,即日期和时间,然后从 S 列中提取速度。我对如何做到这一点有一个通用的想法,即:将整个第一行提取到一个字符串中,并忽略除 WAST 和 S 或类似内容之外的所有内容。但即便如此,我应该如何只在我想要的列下获得每个值?请帮忙。
Main.cpp:
#include <iostream>
#include <string>
#include <fstream>
#include "Date.h"
#include "Time.h"
#include "Vector.h"
using namespace std;
typedef struct {
Date d;
Time t;
float speed;
}WindLogType;
int main()
{
Date dTest;
Time tTest;
float speedtest = 52.5;
Vector<WindLogType> windlog;
ifstream infile("testinput2.csv");
if(!infile){
cout << "File not found.";
return -1;
};
WindLogType windlog2;
//int i = 0;
while(!infile.eof()){
infile >> windlog2.d >> windlog2.t >> windlog2.speed;
windlog.add(windlog2);
}
for(int i = 0; i < windlog.size(); i++){
cout << windlog[i].d << " " << windlog[i].t << " Speed: " << windlog[i].speed << endl;
}
infile.close();
return 0;
}
您在这里可以做的是为您的结构 WindLogType
编写一个流提取运算符,用于一次一行地读取文件,从该行中提取您需要的信息并填充结构。
std::getline
不仅可以用来读取整行,还可以使用定界符标记字符串。
您可以尝试使用一些评论来解释以下内容:
#include <fstream>
#include <string>
#include <sstream>
using Date = std::string;
using Time = std::string;
typedef struct {
Date d;
Time t;
float speed;
} WindLogType;
std::istream& operator >> (std::istream& is, WindLogType& sl) {
// Read a complete line
std::string line;
if (std::getline(is, line)) {
auto iss = std::istringstream{line};
// Read date from line (up to space)
std::getline(iss, sl.d, ' ');
// Read time (up to ',')
std::getline(iss, sl.t, ',');
std::string speed;
// Read speed (up to next comma)
std::getline(iss, speed, ',');
sl.speed = std::stof(speed);
}
return is;
}
int main()
{
std::ifstream infile("testinput2.csv");
if (!infile) {
std::cout << "File not found.";
return -1;
};
Vector<WindLogType> windlog;
std::string str;
std::getline(infile, str); // skip the first line
WindLogType windlog2;
while (infile >> windlog2) {
windlog.add(windlog2);
}
return 0;
}
流提取运算符 (>>
) 从文件中读取一行。使用该行,它从中创建一个 std::istringstream 对象,然后使用 std::getline
.
我不知道你的 Date
和 Time
类型是如何定义的。我刚刚将它们别名为 std::string
。您必须自己对字符串进行处理。
希望这有用。
编辑:
你不能while(infile >> windlog2.d >> windlog2.t >> windlog2.speed)
的原因是>>
读到白色space/newline。您的数据有点复杂:它是逗号分隔的,并且您已经解析了日期和时间字段。上述方法的好处是它允许您将数据直接流式传输到 WindLog
结构中。
如果您真的不想为您的类型使用流提取运算符,您可以使用相同的代码。它将是这样的:
std::string line;
std::getline(infile, line); // skip the first line
while (std::getline(infile, line)) {
WindLogType sl;
auto iss = std::istringstream{ line };
// Read date from line (up to space)
std::getline(iss, sl.d, ' ');
...
}
我个人更喜欢为一种类型使用流提取运算符,因为它将所有读取操作封装在一个函数中,但如果您想进行一些其他处理,则可以采用第二种方法。