C-如何用空字符分配数组的任何未填充部分,然后将其写入文件中



我正在尝试获取以下功能,将三件事放入文件中:第一,最后和ssn。首先是30个字符长,最后30个字符长,而SSN长9个字符。

我想在文件中发生的事情是我输入以下信息:第一:约翰最后:史密斯SSN:123456789

这是应该加载到文件中的内容(所有一行(:

john 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0smith 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0123456789

但是,所有负载通常是约翰(垃圾(史密斯(垃圾(123456789。

我如何做到这一点,以便当我将这3件事写入文件中时,它们在每个未使用的空间中也有空字符?

void addStudents(struct student createStudent) {
    struct student *object = malloc( sizeof( struct student ) );
    memcpy(object->first, createStudent.first, 30);
    memcpy(object->last, createStudent.last, 30);
    memcpy(object->ssn, createStudent.ssn, 9);
    FILE *fp;
    fp = fopen("students.db", "a");
    fseek( fp, numStudents * sizeof( struct student ), SEEK_SET );
    fwrite( object, sizeof( struct student ), 1, fp );
}

这是结构学生的定义:

struct student {
    char first[30];
    char last[30];
    char ssn[9];
};

编辑:我想要文件中的空字符。如所示,打开文件并完全读取为" John 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0smith 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0123456789",包括空字符。有没有办法这样做?我希望能够访问该文件,并有效地告诉程序从SSN的开头到姓氏的开头"回去" 30个字符。

strcpy和strncpy确实可以通过垃圾出现解决问题,但它们不包括文件中的" 0"字符。

代码正在使用fwrite()将结构(struct student(转储到文件中。fwrite()只是写一个二进制斑点,它不在乎弦线或数据初始化。

您会得到很多垃圾,因为传入的createStudent结构包含很多垃圾。它有垃圾,因为C不会自动初始化成员(这是浪费时间(。如果您要它们"清洁",则必须明确编码。

可以通过调用memset()函数将数据加载到其中之前清除结构:

memset( object, 0, sizeof( *object ) );

它将填充为0/nulls。由于C-串以" 0"(二进制0(终止,这清除了所有垃圾的字符串阵列。请注意,如果书面数据中有垃圾,它实际上不会损害您的过程,因此只要在此过程中保留字符串终结器即可。阵列[abcsome-junk]看起来像" ABC",当用作字符串时。

无论如何,在结构最初用数据编写之前,请初始化。OP的代码不包括此部分,因此我将其处理到addStudents()函数中。(并注意:您根本没有处理numStudents(。

#define MAX_NAME_SIZE 29  
#define MAX_SSN_SIZE   8
struct student 
{
    char first[ MAX_NAME_SIZE + 1 ];
    char last[ MAX_NAME_SIZE + 1 ];
    char ssn[ MAX_SSN_SIZE + 1 ];
};
void addStudents(struct student createStudent) 
{
    struct student *object = malloc( sizeof( struct student ) );
    if ( object != NULL )
    {    
        memset( object, 0, sizeof( *object ) );  // fill with 
        // Note: string buffers zeroed and 1-char bigger, so strncpy() is safe
        strncpy( object->first, createStudent.first, MAX_NAME_SIZE );
        strncpy( object->last,  createStudent.last,  MAX_NAME_SIZE );
        strncpy( object->ssn,   createStudent.ssn,   MAX_SSN_SIZE );
        FILE *fp;
        fp = fopen("students.db", "a");
        if ( fp != NULL )
        {
            // TODO: check these functions don't return error
            fseek( fp, numStudents * sizeof( struct student ), SEEK_SET );  // Necessary when open "a"?
            fwrite( object, sizeof( struct student ), 1, fp );
            fclose( fp );  // Don't forget to close
        }
        else
        {
             // TODO: handle file error
        }
    }
    else
    {
        // TODO - handle memory error
    }
}

在所有记录体之前,您应该考虑将记录数写入文件顶部。这使您可以阅读并轻松更新它。

使用memset((和strcpy((

malloc()之后放置以下内容:

memset(object, 0, sizeof(struct student));

并在memcpy()上使用strcpy()

strcpy(object->first, createStudent.first);
strcpy(object->last, createStudent.last);
strcpy(object->ssn, createStudent.ssn);

假设createStudent的null终止字符串,这将使整个结构无效,并将仅复制直到终止NULL,这些字符串永远不会超过定义的相关object(如果不是,则可以使用strncpy()(。<</

相关内容

最新更新