2011-06-21 129 views
4

我正在使用C/UNIX并且有一个包含记录数的输入文件。我已将每条记录映射到一个结构,并通过在数据库的记录中添加缺少的信息将结构写入输出文件。将结构写入文件C

我的问题是写结构(由字符数组组成)回到文件。我正在使用

fwrite(&record, sizeof(record), 1, out); 
    fwrite("\n", 1, 1, outfd); 

这将在每个成员之后将数据写入输出文件中,终止NULL'\ 0'。请让我知道如何在每个成员之后没有终止'\ 0'的情况下将此结构写入文件。

+2

请提供结构定义,以便我们知道您正在使用什么。此外,你正在试图处理你刚写下的数据。如果它被写入另一个C程序,这可能是一个功能。 –

+2

请注意,这样做意味着您的格式不可移植。 – jamesdlin

回答

5

我会想象那些0是字符数组的一部分 - 它们在每个C字符串的末尾。如果您需要将字符串写入文件而不用零,则可以编写单个字符数组,只写入字符而不写入尾部零(您可以使用strlen()查找此长度),即,

fwrite (theCharArray,1,strlen(theCharArray),out);

但是你可能需要写一些关于每个字符串到文件长度的信息。

+0

谢谢欧内斯特,是的,这是真的,那些尾随'\ 0'是字符数组的一部分。编写单个字符串是唯一的解决方案。该结构非常大,有100名成员。请建议。 –

+1

@Jerry Coffin建议使用由'offsetof'和一个循环计算出来的数值数组;这实际上会导致*更多*,尽管稍微简单一些的代码行。我可以想到的一个疯狂的事情是,如果'struct'完全由char数组组成,那么你可以有一个迭代sizeof(struct)次的for循环,在每一步前进一个指针,并写入非零字符到文件,一次一个。整个过程只需要几行代码,并且对结构的修改会很有效。缺点是表现可能不会那么好。 –

3

这会写出一个与存储在内存中一样的record - 但编译器在成员之间自由插入填充,如果存在,则会写出填充字节中发生的任何值。许多(大多数?)编译器有不可移植的方法来阻止它们插入该填充 - MSVC使用#pragma pack(1),gcc使用__attribute(__packed__)(至少某些版本也支持#pragma pack语法)。

您也可以将record定义为包含一些零字节作为数据的一部分(例如,包含零终止符的字符串以使它们成为字符串)。由于您未显示record的定义,因此很难猜测这是否适用。

编辑:根据您的评论,似乎后者是这种情况。我要做的第一点是删除这些可能不是一个好主意。如果你删除它们,你必须做来让程序读取数据,知道一个字段结束和下一个字段开始(除非字段是固定宽度,可以隐式处理)。

最明显的可能性是在每个字段前面加上其长度。这具有以下优点:如果/当您要查找文件时,您可以从一个字段到下一个字段而不读取数据以查找终止字节。然而,通常情况下,我会使用一个索引 - 一个文件,其中包含文件偏移到数据中的连续记录(可能还有每个记录的一些关键数据,因此您可以根据记录的内容快速搜索),所以您可以快速查找记录的位置并读取其数据。除非你有非常大的领域,寻求个别领域很少成就很多。

+0

正在写个人会员是唯一的解决方案来获得这个 –

+1

@Sachin Chourasiya:很多,是的。但是,通过使用'offsetof'来创建偏移量到字段开头的数组,可以避免这么麻烦,因此您可以将这些字段写入循环中,而不是对'fwrite'进行100次单独写入的调用(或投入等)。请参阅:http://stackoverflow.com/questions/5088358/breaking-a-single-string-into-multiple-strings-c/5088496#5088496为例。 –

+0

@Sachin:想象一下你可以把''\ 0''(和下面的字节)取出来。你如何确定下一位成员的开始? – pmg