c++ - 如何从文本文件中读取数据并将其存储到C++中的数组中
问题描述
我正在尝试从文本文件中读取数据并将其存储到数组中。我需要它来解决 FEM 问题。假设我的文本文件如下:
node: 1,2,3,4,5,6,7,8,9,10
x: 4,4,3.75,3.76773151,3,3.59192947,4,3.5,3.55115372,3.375, 3.71330586
y: 3,275,3,2.65921885,2.79192947,2.5,3,2.55115372,2.78349365,2.36222989
z: 0,0,0,0,0,0,0,0,0,0
我想将此数据从文本文件存储到 10*4 矩阵 ( myarray[10][4]
) 中。我还需要将此数组的每一列存储到一个向量中。假设我的向量是:
double x[10];
double y[10];
double z[10];
for (int i = 0; i < 10; i++)
{
x[i] = myarray[i][1];
y[i] = myarray[i][2];
z[i] = myarray[i][3];
}
我写了这样的代码:
int main()
{
string line;
string coordinate[10][4];
ifstream mesh("mesh.txt");
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 4; ++j)
{
if (getline(mesh, line, ';'))
{
coordinate[i][j] = line;
cout << coordinate[i][j] << endl;
cout << "mesh : " << line[0] << endl;
}
}
}
mesh.close();
}
现在我的问题是,当我想将每一列坐标放入一个向量时,我得到了这个错误:
不存在从字符串到双精度的合适转换函数
我不明白这个错误,需要帮助来修复它。
解决方案
一种迭代方式可能像这样,在定制的迭代器类中使用拆分器。它似乎很复杂,但我认为它很容易维护。请注意,迭代器类是这个好答案的修改版本。
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
template <typename T>
class istream_line_iterator : public std::iterator<std::input_iterator_tag, T> {
std::istream* stream;
public:
// Creating from a stream or the end iterator.
istream_line_iterator(std::istream& s) : stream(&s) { dropLeadingSpace(); }
istream_line_iterator() : stream(nullptr) {}
// Copy
istream_line_iterator(istream_line_iterator const& copy)
: stream(copy.stream) {}
istream_line_iterator& operator=(istream_line_iterator const& copy) {
stream = copy.stream;
return *this;
}
// The only valid comparison is against the end() iterator.
// All other iterator comparisons return false.
bool operator==(istream_line_iterator const& rhs) const {
return stream == nullptr && rhs.stream == nullptr;
}
bool operator!=(istream_line_iterator const& rhs) const {
return !(*this == rhs);
}
// Geting the value modifies the stream and returns the value.
// Note: Reading from the end() iterator is undefined behavior.
T operator*() const {
T value;
(*stream) >> value;
return value;
}
T* operator->() const; // Not sure I want to implement this.
// Input streams are funny.
// Does not matter if you do a pre or post increment. The underlying stream
// has changed. So the effect is the same.
istream_line_iterator& operator++() {
dropLeadingSpace();
return *this;
}
istream_line_iterator& operator++(int) {
dropLeadingSpace();
return *this;
}
private:
void dropLeadingSpace() {
// Only called from constructor and ++ operator.
// Note calling this on end iterator is undefined behavior.
char c;
while ((*stream) >> std::noskipws >> c) {
if (c == '\n') {
// End of line. So mark the iterator as reaching end.
stream = nullptr;
return;
}
if (!std::isspace(c) && c != ',') {
// Found a non space character so put it back
stream->putback(c);
return;
}
}
// End of stream. Mark the iterator as reaching the end.
stream = nullptr;
}
};
int main() {
std::ifstream ifs("1.in");
std::string line;
std::vector<std::vector<double>> vec;
while (std::getline(ifs, line)) {
std::istringstream iss(line);
std::string pre;
iss >> pre;
std::vector<double> line_vec;
auto beg = istream_line_iterator<double>(iss);
auto end = istream_line_iterator<double>();
std::copy(beg, end, std::back_inserter(line_vec));
vec.push_back(std::move(line_vec));
}
for (const auto& inner : vec) {
for (auto d : inner) {
std::cout << d << ' ';
}
std::cout << std::endl;
}
return 0;
}
推荐阅读
- angularjs - UI Bootstrap 弹出框没有事件监听器
- python - 解释 keras 功能中的 SGD
- java - 跳过 RegEx 分组
- wordpress - 如何将 Joomla K2 迁移到 Wordpress
- amazon-web-services - 尝试使用 AWS Amplify 从 Android 应用程序注册时遇到注册错误
- curl - cookies.txt 不适用于 Httrack 版本 3.49-2
- python-3.x - 在调度程序和 bash 脚本下读取泡菜文件的权限被拒绝
- android-studio - 当我将语言更改为阿拉伯语时如何解决颜色选择器中的大小问题
- android - Dagger 2.25 java.lang.NoClassDefFoundError: dagger/shaded/auto/common/BasicAnnotationProcessor
- android - Android中的自定义TextView