在C++中读取csv文件中的特定行
Reading a particular line in a csv file in C++
我有一个csv文件,其中包含许多行数据。我的函数将lineNum作为参数传递。因此,当用户输入4作为lineNum时,我想读取csv文件中的第4行。我认为一个很好的方法是查找并计数,当计数为lineNum-1时停止,然后继续读取下一行。我认为这是一种不错的方式,但我对实施方式完全感到困惑。希望得到一些帮助这是我的代码
void ReadCsv( int lineNum){
ifstream inFile ("/media/LOGGING/darsv1.csv");
string line;
string dataArray[226900];
int i = 0;
int endofline =0;
int a, b, c, d, e;
while (getline (inFile, line)) {
//printf(line.c_str());
istringstream linestream(line);
string item ="";
int itemnum = 0;
if (lineNum==1) {
printf(" line number is 1. ");
while (getline (linestream, item, ',')) {
itemnum++;
dataArray[i]=item;
i++;
}
}
else {
while (getline (linestream, item,'n')) {
endofline=endofline+1;
cout<<" went through line number "<<endofline<<" ";
printf(" inside inner while, looking for line. ");
if (endofline == lineNum-1) {
printf(" found the correct line. ");
while (getline (linestream, item, ',')) {
itemnum++;
dataArray[i]=item;
i++;
printf(" found the correct data in the line. ");
}
}
}printf(" out of inner while. ");
}printf(" out of outer if. ");
}
printf(" out of all while loops. ");
}
如果您只需要读取CSV中的某一行,然后从该行读取逗号分隔的项目,那么这可能会有所帮助。我同意@sanjaya-r的观点,你应该保持简单。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main (int argc, const char * argv[]) {
string line, csvItem;
ifstream myfile ("/tmp/file.csv");
int lineNumber = 0;
int lineNumberSought = 3; // you may get it as argument
if (myfile.is_open()) {
while (getline(myfile,line)) {
lineNumber++;
if(lineNumber == lineNumberSought) {
cout << line << endl; ;
istringstream myline(line);
while(getline(myline, csvItem, ',')) {
cout << csvItem << endl;
}
}
}
myfile.close();
}
return 0;
}
这是不可编译的。
这是你的虫子吗?
if (endofline = lineNum-1)
您正在将lineNum - 1
分配给endofline
。使用==
进行比较。
保持简单。让一个getline循环完成所有工作。第一线无需特殊情况。
// ...
linesToGo = linesNum - 1;
string line;
while(getline(infile,line) && (linesToGo > 0)) {
linesToGo--;
}
if (linesToGo == 0) {
cout << "found line:," << line << endl;
// process here.
} else {
count << "not enough lines in file." << endl;
}
另外,不要把cout和printf混在一起。
在文本文件中的特定行中,有一个SO问答,您可以在其中找到Xeo的答案,这是我最喜欢的答案。Xeo使用istream::ignore
,充分的功能使其成为清洁快速的解决方案。
以下是一个基于上述答案的完整示例(带有一些修饰):
#include <fstream>
#include <limits>
#include <string>
#include <iostream>
using namespace std;
fstream& Go2Line(fstream& file, unsigned int num)
{
file.seekg(ios::beg);
for(unsigned int i=0; i < num - 1; ++i)
file.ignore(numeric_limits<streamsize>::max(),'n');
return file;
}
int main()
{
fstream file("/media/LOGGING/darsv1.csv",ios_base::in);
if (!file)
cout << "Unable to open file /media/LOGGING/darsv1.csvn";
else
{
int Number2Go = 4;
Go2Line(file, Number2Go);
if (!file)
cout << "Unable to reach line " << Number2Go << ".n";
else
{
string line;
getline(file,line);
cout << "Line " << Number2Go << "reached successfully. It is:n" << line;
}
}
return 0;
}
我创建了以下程序,因为我正在练习C++算法。虽然这个解决方案看起来很有效,但请谨慎对待(也就是说,有些人可能认为它太复杂了)。另一方面,它可以帮助您理解迭代器、流和算法的某些方面。
#include<iostream>
#include<fstream>
#include<algorithm>
#include<iterator>
/**
@brief A trick proposed by Jerry Coffin / Manuel (SO users) to
create a line-by-line iterator. This makes an `std::istream`
yield lines as opposed to chars.
*/
struct Line
: std::string {
friend std::istream & operator>>(std::istream& is, Line& line) {
return std::getline(is, line);
}
};
/**
@brief This predicate contains an internal count of the lines read
so far. Its `operator()(std::string)` will evaluate to `true` when
the current line read equals the target line (provided during
construction).
*/
struct LineNumberMatcher {
unsigned int target_line;
unsigned int current_line;
LineNumberMatcher(unsigned int target_line)
: target_line(target_line),
current_line(0) { }
bool operator()(const std::string& line) {
return ++current_line == target_line;
}
};
int main(int argc, char* argv[]) {
if(argc != 3) {
std::cout<<"usage: "<<argv[0]<<" filename line"<<std::endl;
return 0;
}
std::string filename(argv[1]);
unsigned int target = std::stoi(argv[2]);
// Build the LineNumberMatcher
LineNumberMatcher match(target);
// Provide a scope after which the file will be automatically closed
{
// Open the file
std::ifstream fp(filename);
// Copy the line to standard output if the LineNumberMatcher
// evaluates to true (that is, when the line read equals the target
// line)
std::copy_if(std::istream_iterator<Line>(fp),
std::istream_iterator<Line>(),
std::ostream_iterator<std::string>(std::cout, "n"),
match);
}
return 0;
}
使用C++11支持编译(在我的例子中,g++ spitline.cpp -std=c++111
,使用GCC 4.7.2)。示例输出:
$ /a.out spitline.cpp 7
@brief A trick proposed by Jerry Coffin / Manuel (SO users) to
这确实是我源代码中的第7行。
相关文章:
- 正在将csv文件读取为双精度矢量
- 如何选择在 csv 文件中输出的位置
- 有没有办法在不使用 getline() 的情况下从.csv文件中读取?
- 如何从 CSV 获取数据并将其存储在 C++ 中的表对象中
- 无法读取C++中的 CSV 文件
- 流:CSV 文件中的换行符
- 是否可以使用 Python csv 阅读器读取使用 C++ std::setw 生成的文件?
- 使用从文件(stod、strtod、atof)中提取的数据C++从字符串转换为双精度.csv
- 将一维数组写入 CSV C++中的不同列?
- 如何从CSV加载堆栈?C++
- 如何正确格式化csv文件?
- 正在分析CSV文件-C++
- 如何获取组件和搜索 CSV 文件
- C++ 中的 CSV 文件管理(特别是设置标头和每个标头将分别具有的值)
- 无法逐行读取.csv文件
- 以CSV格式编写特征矢量Xd
- 非常快速地阅读 CSV 文件
- 读取和存储 CSV 数据
- 该程序将.csv文件中的一系列单词放入数组中,然后随机生成句子.但它不起作用
- CSV文件之间的差异,使用getline()产生不同的结果