我的fwrite()和fread()在这里处理二进制文件的问题是我的源代码,而对于bottem来说是我的读写。现在它正在回归' jake'当我跑它,没有别的。有人告诉我写一个转储缓冲区函数来处理二进制字符。另外这里也是文本文件,我写的是一个名为info.bin的空白文件。 PS我知道将zip保存为int是不好的做法,但这正是我教授所要求的。
文件:
mike|203-376-5555|7 Melba Ave|Milford|CT|06461
jake|203-555-5555|8 Melba Ave|Hartford|CT|65484
snake|203-555-5555|9 Melba Ave|Stamford|CT|06465
liquid|203-777-5555|2 Melba Ave|Barftown|CT|32154
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LINE 80
#define RECORDS 10
struct info{
char name[100];
char number[100];
char address[100];
char city[100];
char state[100];
int zip;
};
void dump_buffer(void *buffer, int buffer_size)
{
int x;
for(x = 0; x < buffer_size; x++)
{
printf("%c",((char *)buffer)[x]);
}
}
int i, j, seeker;
int main(int argc, char* argv[])
{
char *buffer;
struct info input_records[RECORDS];
int nrecs = 0;
unsigned long fileLen;
char line[LINE];
FILE *fp = NULL;
FILE *fpbin = NULL;
FILE *fpread = NULL;
if (argc != 2)
{
printf ("ERROR: you must specify file name!\n");
return 1;
}
/* Open file */
fp = fopen(argv[1], "r");
if (!fp)
{
perror ("File open error!\n");
return 1;
}
while (!feof (fp)) {
fgets(line, sizeof(line),fp);
char* tok = strtok(line, "|");
while(tok != NULL)
{
strcpy(input_records[nrecs].name, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].number, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].address, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].city, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].state, tok);
tok = strtok(NULL, "|");
input_records[nrecs].zip = atoi(tok);
tok = strtok(NULL, "|");
}
nrecs++;
}
fpbin = fopen("info2.bin", "wb");
if (!fp)
{
perror ("File open error!\n");
return 1;
}
for(i = 0; i < 4; i++)
{
fwrite(&input_records[i], sizeof(struct info), 200000, fpbin);
}
fclose(fpbin);
fpread = fopen("info2.bin", "rb");
fseek(fpread, 0, SEEK_END);
fileLen = ftell(fpread);
fseek(fpread, 0, SEEK_SET);
buffer = (char *)malloc(sizeof(struct info));
fread(buffer, fileLen, 1, fpread);
dump_buffer(buffer, sizeof(buffer));
fclose(fpread);
fclose(fp);
free(buffer);
return 0;
}
答案 0 :(得分:4)
fwrite(&input_records[i], sizeof(struct info), 200000, fpbin);
您刚刚告诉fwrite
将200000 * sizeof(struct info)
字节写入文件,从地址input_records[i]
开始。它访问的内存远远超出为input_records
分配的内存,行为未定义,但分段错误并非不可能。我真的很惊讶,显然它并没有让你崩溃。
buffer = (char *)malloc(sizeof(struct info));
fread(buffer, fileLen, 1, fpread);
您尝试将fileLen
字节读入大小为sizeof(struct info)
的缓冲区。如果fileLen > sizeof(struct info)
,那又是未定义的行为,如果fileLen
足够大,可能会崩溃。
每次都应该让fwrite
一个大小为sizeof(struct info)
的对象,并且应该为您读入的缓冲区分配fileLen
个字节(或读入大小sizeof(struct info)
)的块。您应该检查fwrite
和fread
的返回值,以了解它们是否成功写入/读取所需数据并正确处理故障。
fpbin = fopen("info2.bin", "wb");
if (!fp)
{
您在此处检查了错误的FILE*
,并且根本没有检查fpread
。
此外,您将错误的计数传递给dump_buffer
,
dump_buffer(buffer, sizeof(buffer));
buffer
是char*
,因此sizeof buffer
的大小为char*
,通常为4或8个字节。你应该在那里传递缓冲区的分配大小。
并且,在阅读原始文件时,
while (!feof (fp)) {
fgets(line, sizeof(line),fp);
feof(fp)
只有在达到文件结束时尝试读取后才会变为真,您应该将循环条件更改为
while(fgets(line, sizeof line, fp) != NULL) {
最后,如果输入文件包含格式错误的数据或行太长,您的令牌化代码将会严重失败。您还应该在那里添加支票,这样就不会将NULL
传递给strcpy
或atoi
。