如何在C ++中将文本文件保存为带字符串的结构

时间:2019-05-01 21:32:01

标签: c++

我想将文件的内容保存到结构中。我尝试使用seekg并阅读以对其进行写操作,但是它不起作用。

我的文件类似于:

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;
}

它不编译,因为它不希望我在读取函数上使用ts。有另一种方法吗?

2 个答案:

答案 0 :(得分:1)

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

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:拆分名称
由于名字和姓氏之间没有分隔符,因此您可能需要一个可能的名字列表,并使用该列表来找出名字的结尾和姓氏的开头。

答案 1 :(得分: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'之后使用相同数量的十六进制数字。我通常分别使用2和4位数字。原因:如果您编写较少数量的十六进制数字,例如,如果仅使用流<<“ \ x” << hex << unsigned(theChar),则当字符串中的下一个字符碰巧是十六进制数字。例如,如果字符串包含“ \ xF”后跟“ A”,则应输入“ \ x0FA”,而不是“ \ xFA”。
  •   
  • 如果您不对'\ n'等字符使用某种转义序列,请注意操作系统不会弄乱您的字符串数据。特别是,如果您打开没有std :: ios :: binary的std :: fstream,则某些操作系统会转换行尾字符。   字符串数据的另一种方法是在字符串数据前添加整数长度,例如,将“ now is the time”写为15:now is time。请注意,这可能会使人们难以读取/写入文件,因为紧随其后的值可能没有可见的分隔符,但您仍然会发现它很有用。
  •   

基于文本的序列化/反序列化约定有所不同,但是每行一个字段是一种公认​​的惯例。