我有一个结构:
struct foo {
int a;
string b;
bool c;
//... ad infinitum
};
我想用 .txt 文件中的数据加载它,如下所示:
string a, b, c;
string* ptr[] = { &a, &b, &c };
ifstream file("input.txt");
size_t i = 0;
while (file >> *ptr[i])
(i < 3) ? i++ : i = 0;
//convert a, c to int and bool, then assign
但是然后我将不得不手动将它们从字符串转换为 int 或 bool 类型,无论如何都可以加载所有它们而无需随后进行转换(也许使用 void* ptr[] )?
我不想这样:
while (!file.eof()){
file>>a;
file>>b;
file>>c;
}
因为 Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong? ,我不想
file>>
10 次。我也没有学习过 lexical_cast 或运算符重载之类的东西,因此任何与它们相关的答案都非常有帮助,但可能无法解决我的问题。
这是txt文件:
19127519
Jame Howard
0
19124567
Jacky Thomas
1
14527890
Lucas
1
最佳答案
您的解决方案中有几个问题
std::string
和 int
时,你只读取 bool
std::string
的方式将任何空格视为分隔符,这意味着“Jame Howard”不是读入一个字符串而是两个分隔的,这不是您的代码在索引管理中假设的 当您打开文件时,请始终检查您是否能够做到。
你可以这样做:
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
struct foo {
int a;
std::string b;
bool c;
//... ad infinitum
};
int main()
{
std::ifstream file("input.txt");
if (!file)
std::cerr << "cannot open input.txt" << std::endl;
else {
std::vector<foo> foos; // to save all struct
foo f; // to read one struict
while ((file >> f.a) &&
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n') && // flush rest of line
std::getline(file, f.b) &&
(file >> f.c))
foos.push_back(f);
// check
for (auto f : foos)
std::cout << f.a << ' ' << f.b << ' ' << f.c << std::endl;
}
}
字符串可以包含空格,因此不可能在 f 是 foo 的情况下执行
file >> f.b
,可以使用 getline
,但由于每个元素都在单独的行中,因此有必要在读取 int 后刷新行尾。编译和执行:
pi@raspberrypi:~ $ g++ -g -Wall f.cc
pi@raspberrypi:~ $ cat input.txt
19127519
Jame Howard
0
19124567
Jacky Thomas
1
14527890
Lucas
1
pi@raspberrypi:~ $ ./a.out
19127519 Jame Howard 0
19124567 Jacky Thomas 1
14527890 Lucas 1
pi@raspberrypi:~ $
与其将代码放在 main 中读取 foo ,不如定义
operator >>
(如果需要 operator <<
)更自然,所以:#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <limits>
struct foo {
int a;
std::string b;
bool c;
//... ad infinitum
};
std::istream& operator >>(std::istream & in, foo & f) {
if ((in >> f.a) &&
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n') && // flush rest of line
std::getline(in, f.b))
in >> f.c;
return in;
}
int main()
{
std::ifstream file("input.txt");
if (!file)
std::cerr << "cannot open input.txt" << std::endl;
else {
std::vector<foo> foos;
foo f;
while (file >> f)
foos.push_back(f);
for (auto f : foos)
std::cout << f.a << ' ' << f.b << ' ' << f.c << std::endl;
}
}
如果 foo 具有私有(private)属性
operator <<
必须在 foo 中声明 friend
关于c++ - 读取文件以构造具有多种成员类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61427463/