file.txt文件的内容如下:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
其中53是一个坐标对。 如何在c++中逐行处理这个数据?
我能够得到第一行,但是我如何得到文件的下一行呢?
ifstream myfile;
myfile.open ("file.txt");
file.txt文件的内容如下:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
其中53是一个坐标对。 如何在c++中逐行处理这个数据?
我能够得到第一行,但是我如何得到文件的下一行呢?
ifstream myfile;
myfile.open ("file.txt");
当前回答
使用ifstream从文件中读取数据:
std::ifstream input( "filename.ext" );
如果你真的需要逐行阅读,那么可以这样做:
for( std::string line; getline( input, line ); )
{
...for each line in input...
}
但你可能只需要提取坐标对:
int x, y;
input >> x >> y;
更新:
在你的代码中,你使用ofstream myfile;,然而ofstream中的o代表输出。如果你想从文件中读取(输入)使用ifstream。如果你既想读又想写,请使用fstream。
其他回答
既然你的坐标是成对的,为什么不为它们写一个结构呢?
struct CoordinatePair
{
int x;
int y;
};
然后你可以为istreams写一个重载的提取操作符:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
然后你可以把坐标文件直接读入一个向量,像这样:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
char filename[] = "coordinates.txt";
std::vector<CoordinatePair> v;
std::ifstream ifs(filename);
if (ifs) {
std::copy(std::istream_iterator<CoordinatePair>(ifs),
std::istream_iterator<CoordinatePair>(),
std::back_inserter(v));
}
else {
std::cerr << "Couldn't open " << filename << " for reading\n";
}
// Now you can work with the contents of v
}
这个答案适用于visual studio 2017,如果你想从文本文件中读取相对于编译后的控制台应用程序的位置。
首先将文本文件(在本例中为test.txt)放入解决方案文件夹。编译完成后,将文本文件与applicationName.exe保存在同一文件夹中
spedfy”C: \ Users \ \ \ \ \ " solutionName休息”“solutionName来源"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
// open the file stream
inFile.open(".\\test.txt");
// check if opening a file failed
if (inFile.fail()) {
cerr << "Error opeing a file" << endl;
inFile.close();
exit(1);
}
string line;
while (getline(inFile, line))
{
cout << line << endl;
}
// close the file stream
inFile.close();
}
展开接受的答案,如果输入是:
1,NYC
2,ABQ
...
你仍然可以应用同样的逻辑,像这样:
#include <fstream>
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int number;
std::string str;
char c;
while (infile >> number >> c >> str && c == ',')
std::cout << number << " " << str << "\n";
}
infile.close();
在c++中,可以通过一些不同的方式逐行读取文件。
使用std::getline()循环
最简单的方法是打开std::ifstream并使用std::getline()调用进行循环。代码很干净,易于理解。
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
使用Boost的file_description_source
另一种可能是使用Boost库,但代码会更冗长一些。其性能与上面的代码非常相似(使用std::getline()进行循环)。
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>
namespace io = boost::iostreams;
void readLineByLineBoost() {
int fdr = open(FILENAME, O_RDONLY);
if (fdr >= 0) {
io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
io::stream <io::file_descriptor_source> in(fdDevice);
if (fdDevice.is_open()) {
std::string line;
while (std::getline(in, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
fdDevice.close();
}
}
}
[最快]使用C代码
如果性能对您的软件至关重要,您可以考虑使用C语言。这段代码可以比上面的c++版本快4-5倍,参见下面的基准测试
FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
// using printf() in all tests for consistency
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
基准测试——哪个更快?
I have done some performance benchmarks with the code above and the results are interesting. I have tested the code with ASCII files that contain 100,000 lines, 1,000,000 lines and 10,000,000 lines of text. Each line of text contains 10 words in average. The program is compiled with -O3 optimization and its output is forwarded to /dev/null in order to remove the logging time variable from the measurement. Last, but not least, each piece of code logs each line with the printf() function for consistency.
结果显示了每段代码读取文件所花费的时间(单位为毫秒)。
两种c++方法之间的性能差异很小,在实践中不应该有任何区别。C代码的性能使基准测试令人印象深刻,并且可以在速度方面改变游戏规则。
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms
虽然不需要手动关闭文件,但如果文件变量的范围更大,那么这样做是个好主意:
ifstream infile(szFilePath);
for (string line = ""; getline(infile, line); )
{
//do something with the line
}
if(infile.is_open())
infile.close();