如何为数组的任何未填充部分分配空字符,然后将其写入文件?
How do I assign any non-filled parts of my array with null characters, and then write it into a file?
我正在尝试使用以下函数将三项内容放入文件中:first、last 和 ssn。首先是 30 个字符,最后是 30 个字符,ssn 是 9 个字符。
我希望在文件中输入以下信息:
第一名:约翰
最后:史密斯
ssn: 123456789
这是应该加载到文件中的内容(全部一行):
john[=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=]smith[=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=]23456789
但是,加载的内容通常是 john(junk)smith(junk)123456789。
我如何做到这一点,当我将这 3 个东西写入文件时,它们在每个未使用的 space 中也有空字符?
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[=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=]smith[=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=]23456789" 读取,包括空字符。有没有办法做到这一点?我希望能够访问该文件并有效地告诉程序 "go back" 从 ssn 开头到姓氏开头的 30 个字符。
Strcpy 和 strncpy 确实解决了出现垃圾的问题,但它们没有在文件中包含“\0”字符。
使用 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
具有空终止字符串,这些字符串永远不会长于定义的相关 object
字符串(如果它是不,你可以使用 strncpy()
).
代码使用 fwrite()
将结构 (struct student
) 转储到文件中。 fwrite()
只写一个二进制 blob,它不关心 string-endings 或数据初始化。
您得到了很多垃圾,因为传入的 createStudent
结构包含很多垃圾。它里面有垃圾,因为 C 不会自动初始化成员(这是浪费时间)。如果你想要它们 "clean",你必须明确地编码。
可以在调用 memset()
函数将数据加载到其中之前清除结构:
memset( object, 0, sizeof( *object ) );
这将填满 0 / NULL。由于 C-strings 以 '\0'(二进制 0)结尾,这会清除字符串数组中的所有垃圾。请注意,如果写入的数据中有垃圾,它实际上不会损害您的进程,因此只要在进程中保留字符串终止符即可。当用作字符串时,数组 [abc[=17=]some-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 [=11=]
// 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
}
}
您应该考虑将记录数写入文件顶部,在所有 record-bodies 之前。这使您可以轻松阅读和更新它。
我正在尝试使用以下函数将三项内容放入文件中:first、last 和 ssn。首先是 30 个字符,最后是 30 个字符,ssn 是 9 个字符。
我希望在文件中输入以下信息: 第一名:约翰 最后:史密斯 ssn: 123456789
这是应该加载到文件中的内容(全部一行):
john[=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=]smith[=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=][=32=]23456789
但是,加载的内容通常是 john(junk)smith(junk)123456789。
我如何做到这一点,当我将这 3 个东西写入文件时,它们在每个未使用的 space 中也有空字符?
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[=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=]smith[=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=][=30=]23456789" 读取,包括空字符。有没有办法做到这一点?我希望能够访问该文件并有效地告诉程序 "go back" 从 ssn 开头到姓氏开头的 30 个字符。
Strcpy 和 strncpy 确实解决了出现垃圾的问题,但它们没有在文件中包含“\0”字符。
使用 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
具有空终止字符串,这些字符串永远不会长于定义的相关 object
字符串(如果它是不,你可以使用 strncpy()
).
代码使用 fwrite()
将结构 (struct student
) 转储到文件中。 fwrite()
只写一个二进制 blob,它不关心 string-endings 或数据初始化。
您得到了很多垃圾,因为传入的 createStudent
结构包含很多垃圾。它里面有垃圾,因为 C 不会自动初始化成员(这是浪费时间)。如果你想要它们 "clean",你必须明确地编码。
可以在调用 memset()
函数将数据加载到其中之前清除结构:
memset( object, 0, sizeof( *object ) );
这将填满 0 / NULL。由于 C-strings 以 '\0'(二进制 0)结尾,这会清除字符串数组中的所有垃圾。请注意,如果写入的数据中有垃圾,它实际上不会损害您的进程,因此只要在进程中保留字符串终止符即可。当用作字符串时,数组 [abc[=17=]some-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 [=11=]
// 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
}
}
您应该考虑将记录数写入文件顶部,在所有 record-bodies 之前。这使您可以轻松阅读和更新它。