duk*_*vin 580 c++ file-io ofstream
file.txt的内容是:
5 3
6 4
7 1
10 5
11 6
12 3
12 4
Run Code Online (Sandbox Code Playgroud)
5 3坐标对在哪里.如何在C++中逐行处理此数据?
我能够得到第一行,但是如何获得文件的下一行?
ifstream myfile;
myfile.open ("text.txt");
Run Code Online (Sandbox Code Playgroud)
Ker*_* SB 871
首先,做一个ifstream:
#include <fstream>
std::ifstream infile("thefile.txt");
Run Code Online (Sandbox Code Playgroud)
两种标准方法是:
假设每行包含两个数字并按令牌读取令牌:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
Run Code Online (Sandbox Code Playgroud)基于行的解析,使用字符串流:
#include <sstream>
#include <string>
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int a, b;
if (!(iss >> a >> b)) { break; } // error
// process pair (a,b)
}
Run Code Online (Sandbox Code Playgroud)你不应该混合使用(1)和(2),因为基于令牌的解析不会吞噬新行,所以如果你getline()在基于令牌的提取之后使用,你最终会得到虚假的空行.已经排队了.
K-b*_*llo 165
用于ifstream从文件中读取数据:
std::ifstream input( "filename.ext" );
Run Code Online (Sandbox Code Playgroud)
如果你真的需要逐行阅读,那么这样做:
for( std::string line; getline( input, line ); )
{
...for each line in input...
}
Run Code Online (Sandbox Code Playgroud)
但您可能只需要提取坐标对:
int x, y;
input >> x >> y;
Run Code Online (Sandbox Code Playgroud)
更新:
在你使用的代码中ofstream myfile;,但oin ofstream代表output.如果要从文件中读取(输入)使用ifstream.如果你想同时读写使用fstream.
Hug*_*ira 43
在C++中逐行读取文件可以通过某些不同的方式完成.
最简单的方法是使用std :: getline()调用打开std :: ifstream和循环.代码简洁易懂.
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
Run Code Online (Sandbox Code Playgroud)
另一种可能性是使用Boost库,但代码更加冗长.性能与上面的代码非常相似(Loop with 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果性能对您的软件至关重要,您可以考虑使用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);
Run Code Online (Sandbox Code Playgroud)
我已经使用上面的代码完成了一些性能基准测试,结果很有趣.我已经使用包含100,000行,1,000,000行和10,000,000行文本的ASCII文件测试了代码.每行文本平均包含10个单词.程序通过-O3优化进行编译,并将其输出转发到/dev/null,以便从测量中删除记录时间变量.最后,但并非最不重要的是,每段代码都会记录每行的printf()功能以保持一致性.
结果显示每段代码读取文件所用的时间(以毫秒为单位).
两种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
Run Code Online (Sandbox Code Playgroud)
Mar*_*rst 11
由于你的坐标是成对的,为什么不为它们写一个结构?
struct CoordinatePair
{
int x;
int y;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以为istreams编写一个重载的提取运算符:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以直接将坐标文件读入这样的矢量:
#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
}
Run Code Online (Sandbox Code Playgroud)
扩展已接受的答案,如果输入是:
1,NYC
2,ABQ
...
Run Code Online (Sandbox Code Playgroud)
您仍然可以应用相同的逻辑,如下所示:
#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();
Run Code Online (Sandbox Code Playgroud)
这个答案适用于 Visual Studio 2017,如果您想从文本文件中读取哪个位置相对于您编译的控制台应用程序。
首先将文本文件(本例中为 test.txt)放入解决方案文件夹中。编译后将文本文件保留在与 applicationName.exe 相同的文件夹中
C:\Users\"用户名"\source\repos\"解决方案名称"\"解决方案名称"
#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();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
虽然不需要手动关闭文件,但如果文件变量的范围较大,最好这样做:
ifstream infile(szFilePath);
for (string line = ""; getline(infile, line); )
{
//do something with the line
}
if(infile.is_open())
infile.close();
Run Code Online (Sandbox Code Playgroud)