C++ 逐行读取用户定义的文本资源文件

C++ 逐行读取用户定义的文本资源文件,c++,resources,scanf,C++,Resources,Scanf,我需要读取文本文件的内容并将值存储到变量中。考虑这个简单的文件: 2 -0.5 -0.5 0.0 0.5 -0.5 0.0 在不使用资源的情况下指定其文件名时,我对fscanf_s执行如下操作: 但它似乎不像我预期的那样工作。点数被正确读取到nPoints变量中,但两个向量的值均为2,-0.5,-0.5 如何将缓冲区中的值保存到Vec3中?还是有一个更简单的选择,我应该考虑?< P>在使用SCASNFFS时,每次都传递同一个缓冲指针,所以它不断地从相同的2个值重读

我需要读取文本文件的内容并将值存储到变量中。考虑这个简单的文件:

2
-0.5    -0.5     0.0
 0.5    -0.5     0.0
在不使用资源的情况下指定其文件名时,我对fscanf_s执行如下操作:

但它似乎不像我预期的那样工作。点数被正确读取到nPoints变量中,但两个向量的值均为2,-0.5,-0.5

如何将缓冲区中的值保存到Vec3中?还是有一个更简单的选择,我应该考虑?

< P>在使用SCASNFFS时,每次都传递同一个缓冲指针,所以它不断地从相同的2个值重读。

每次读取后,需要将指针向前移动。sscanf\u f的返回值是读取的字段数,但您需要消耗的字符数,这可以通过%n格式说明符获得,例如:

char *ptr = buffer;
int consumed;

sscanf_s(ptr, "%d%n", &nPoints, &consumed);
ptr += consumed;

points = new Vec3[nPoints];

for (int n = 0; n < nPoints; ++n) {
    sscanf_s(ptr, "%lf %lf %lf%n", &points[n][0], &points[n][1], &points[n][2], &consumed);
    ptr += consumed;
}
1:要从文件中读取,只需将std::istringstream替换为

或者,如果您想避免分配缓冲区数据的std::string副本的开销,您可以或找到一个第三方实现,它可以从缓冲区中读取数据,甚至可以直接从原始资源中读取数据,例如:

#include <iostream>

SomeCharArrayStreamBuf buf(buffer, size);
std::istream is(&buf);

is >> nPoints;
points = new Vec3[nPoints];

for (int n = 0; n < nPoints; ++n) {
    is >> points[n][0] >> points[n][1] >> points[n][2];
}

一旦切换到C++ I/O流,就可以通过使用C++标准库中的容器和算法来大大简化事情,例如:

#include <vector>

std::vector<Vec3> points; // <-- instead of 'Vec3 *pointers;'

你真的确定用C++编程吗?我正想找的,谢谢!我喜欢使用C风格的I/O,因为它更接近我经常使用的Matlab和Python中的语法。在这种情况下,C++命令的性能更好吗?如果文件中的值是逗号分隔的,它们的工作原理是否相同?对于逗号分隔的数据,请查看,它有一个可选的delim参数,您可以将其设置为“,”。
#include <sstream>

std::istringstream iss(buffer);

iss >> nPoints;
points = new Vec3[nPoints];

for (int n = 0; n < nPoints; ++n) {
    iss >> points[n][0] >> points[n][1] >> points[n][2];
}
#include <iostream>

SomeCharArrayStreamBuf buf(buffer, size);
std::istream is(&buf);

is >> nPoints;
points = new Vec3[nPoints];

for (int n = 0; n < nPoints; ++n) {
    is >> points[n][0] >> points[n][1] >> points[n][2];
}
#include <vector>

std::vector<Vec3> points; // <-- instead of 'Vec3 *pointers;'
#include <iostream>
#include <algorithm>
#include <iterator>

std::istream& operator>>(std::istream &in, Vec3 &v)
{
    in >> v[0] >> v[1] >> v[2];
    return in;
}

strm >> nPoints; // <-- where strm is your chosen istream class object
points.reserve(nPoints); // <-- instead of 'new Vec3[nPoints];'

std::copy_n(std::istream_iterator(strm), nPoints, std::back_inserter(points)); // <-- instead of a manual reading loop