При использовании sscanf_s()
вы передаете ему один и тот же указатель buffer
каждый раз, поэтому он продолжает повторное чтение с одного и того же значения 2
снова и снова.
Вам необходимо продвинуть указательпосле каждого чтения.Возвращаемое значение sscanf_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;
}
Лучшим вариантом является использование ввода-вывода в стиле C ++ вместо ввода-вывода в стиле C.Например, вы можете присвоить данные buffer
для std::istringstream
и затем прочитать из этого 1 , например:
#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];
}
1вместо этого: для чтения из файла просто замените std::istringstream
на std::ifstream
.
Или, если вы хотите избежать затрат на выделение копии std::string
buffer
данных, вы можете написать собственный std::basic_streambuf
класс (или найти стороннюю реализацию), который может читать из вашего buffer
(или даже лучше, из исходного ресурса напрямую), например:
#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 ++, вы можете значительно упростить задачу, используя контейнеры и алгоритмы из стандартной библиотеки C ++, например:
#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