繁体   English   中英

如何在C ++中使用字符串将文本文件保存到结构

[英]How to save text file to struct with string in C++

我想将文件的内容保存到结构中。 我试过使用 seekg 和 read 写入它,但它不起作用。

我的文件是这样的:

johnmayer24ericclapton32

我想将姓名、姓氏和年龄存储在这样的结构中

typedef struct test_struct{
    string name;
    string last_name;
    int age;
} test_struct;

这是我的代码

int main(){

    test_struct ts;
    ifstream data_base;

    data_base.open("test_file.txt");

    data_base.seekg(0, ios_base::beg);
    data_base.read(ts, sizeof(test_struct));

    data_base.close();

    return 0;
}

它不会编译,因为它不希望我在 read 函数上使用 ts。 有没有另一种方式 - 或一种方式 - 做到这一点?

您必须开发特定的算法,因为“字段”之间没有分隔符。

static const std::string input_text = "johnmayer24ericclapton32";
static const std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
static const std::string decimal_digit = "0123456789";

std::string::size_type position = 0;
std::string            artist_name;
position = input_text.find_first_not_of(alphabet);
if (position != std::string::npos)
{
   artist_name = input_text.substr(0, position - 1);
}
else
{
   cerr << "Artist name not found.";
   return EXIT_FAILURE;
}

同样,您可以提取数字,然后使用std::stoi将数字字符串转换为内部表示数字。

编辑 1:拆分名称
由于名字和姓氏之间没有分隔符,您可能需要一个可能的名字列表,并使用它来找出名字的结尾和姓氏的开头。

字符串的序列化/反序列化很棘手。

作为二进制数据,约定是先输出字符串的长度,然后是字符串数据。

https://isocpp.org/wiki/faq/serialization#serialize-binary-format

  • 字符串数据很棘手,因为您必须清楚地知道字符串的主体何时停止。 如果某些字符串可能包含该字符,则不能明确地以 '\\0' 终止所有字符串; 回想一下 std::string 可以存储 '\\0'。 最简单的解决方案是在字符串数据之前写入整数长度。 确保整数长度以“网络格式”写入,以避免 sizeof 和 endian 问题(请参阅早期项目符号中的解决方案)。

这样当读回数据时,你知道期望的字符串长度,并且可以预先分配字符串的大小,然后从流中读取那么多数据。

如果您的数据是非二进制(文本)格式,那就有点棘手了:

https://isocpp.org/wiki/faq/serialization#serialize-text-format

  • 字符串数据很棘手,因为您必须清楚地知道字符串的主体何时停止。 如果某些字符串可能包含这些字符,则不能明确地使用 '\\n' 或 '"' 甚至 '\\0' 终止所有字符串。您可能想要使用 C++ 源代码转义序列,例如,编写 '\\ ' 后跟 'n' 当你看到一个换行符等。在这个转换之后,你可以让字符串一直到行尾(意味着它们被 '\\n' 分隔)或者你可以用 '"' 分隔它们.
  • 如果您对字符串数据使用类似 C++ 的转义序列,请确保在 '\\x' 和 '\\u\u0026#39; 之后始终使用相同数量的十六进制数字。 我通常分别使用 2 位和 4 位数字。 原因:如果您编写较少数量的十六进制数字,例如,如果您只是使用流 << "\\x" << hex << unsigned(theChar),则当字符串中的下一个字符恰好是一个十六进制数字。 例如,如果字符串包含 '\\xF' 后跟 'A',你应该写“\\x0FA”,而不是“\\xFA”。
  • 如果您不对像“\\n”这样的字符使用某种转义序列,请注意操作系统不会弄乱您的字符串数据。 特别是,如果您打开没有 std::ios::binary 的 std::fstream,某些操作系统会转换行尾字符。 字符串数据的另一种方法是用整数长度作为字符串数据的前缀,例如,将“now is the time”写为 15:now is the time。 请注意,这会使人们难以读/写文件,因为紧随其后的值可能没有可见的分隔符,但您仍然可能会发现它很有用。

基于文本的序列化/反序列化约定各不相同,但每行一个字段是公认的做法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM