I/O 在 C 中的二进制文件哪里出错了?
Where did i go wrong with I/O with binary files in C?
我需要使用凯撒密码加密一个句子(还没有完成还需要检查 xyz
和 XYZ
),打开一个二进制文件并在其中写入加密代码。第一个参数应该是二进制文件的名称,然后选择是否要添加一个句子或显示它,如果我输入“#”作为第一个参数,它会提示我输入要从中读取的二进制文件的名称代码。它应该是这样的:
./a.out CODE.DAT >> A >> Kekli kek >> S >> Nhnol nhn >> E.
现在当我这样做时:
./a.out '#' >> CODE.DAT
它给了我正确的字符串直到最后一个字符。像
Nhnol nhM�b�U"
此外,如果我的代码中有任何不良习惯,或者有任何关于编写更干净、更好的代码的建议,如果您能指出来,我将非常高兴。
主要功能:
int main(int argument_count, char **argument_vector) {
if ((**(argument_vector + 1)) == '#') {
FILE *stream;
printf("Name of file: \n");
char stream_name[15];
scanf("%s", stream_name);
if ((stream = fopen(stream_name, "rb")) != NULL) {
char string[50];
fread(string, sizeof(char *), 1, stream);
printf("%s\n", string);
fclose(stream);
}
} else
if (argument_count == 2) {
char character;
do {
printf("ADD [A], SHOW [S], END [E]\n");
scanf("\n%c", &character);
if (character == 'A') {
FILE *stream;
char string[50];
read(string);
code(string);
if ((stream = fopen(*(argument_vector + 1), "wb")) != NULL) {
fwrite(string, sizeof(char *), 1, stream);
fclose(stream);
}
} else
if (character == 'S') {
FILE *stream;
if ((stream = fopen(*(argument_vector + 1), "rb")) != NULL) {
char string[50];
fread(string, sizeof(char *), 1, stream);
printf("%s\n", string);
fclose(stream);
}
}
} while (character != 'E');
} else
return printf("Error"), 1;
}
代码函数:
void code(char *string) {
int i = 0;
for(; string[i] != '[=15=]'; i++) {
if ((int)string[i] == 32)
string[i] = ' ';
else
string[i] += 3;
}
string[i + 1] = '[=15=]';
}
读取函数:
void read(char *string) {
printf("Input string: \n");
scanf("\n%[^\n]%*c", string);
}
问题出在这段代码中:
char string[50];
fread(string, sizeof(char *), 1, stream);
printf("%s\n", string);
fread()
读取二进制数据,因此不添加空终止符。
还有,sizeof(char *)
是错误的。您正在读取一个字符串,而不是一个指针。但是 fread()
用于读取固定大小的数据。如果要读取可变大小的字符串,则应指定 1
作为对象的大小,并且最多 49
个对象(您需要为空终止符留出空间)。 fread
returns 它成功读取的对象数,使用它来确定在何处添加空字节。
char string[50];
size_t n = fread(string, 1, 49, stream);
if (n > 0) {
string[n] = '[=11=]';
printf("%s\n", string);
}
我需要使用凯撒密码加密一个句子(还没有完成还需要检查 xyz
和 XYZ
),打开一个二进制文件并在其中写入加密代码。第一个参数应该是二进制文件的名称,然后选择是否要添加一个句子或显示它,如果我输入“#”作为第一个参数,它会提示我输入要从中读取的二进制文件的名称代码。它应该是这样的:
./a.out CODE.DAT >> A >> Kekli kek >> S >> Nhnol nhn >> E.
现在当我这样做时:
./a.out '#' >> CODE.DAT
它给了我正确的字符串直到最后一个字符。像
Nhnol nhM�b�U"
此外,如果我的代码中有任何不良习惯,或者有任何关于编写更干净、更好的代码的建议,如果您能指出来,我将非常高兴。
主要功能:
int main(int argument_count, char **argument_vector) {
if ((**(argument_vector + 1)) == '#') {
FILE *stream;
printf("Name of file: \n");
char stream_name[15];
scanf("%s", stream_name);
if ((stream = fopen(stream_name, "rb")) != NULL) {
char string[50];
fread(string, sizeof(char *), 1, stream);
printf("%s\n", string);
fclose(stream);
}
} else
if (argument_count == 2) {
char character;
do {
printf("ADD [A], SHOW [S], END [E]\n");
scanf("\n%c", &character);
if (character == 'A') {
FILE *stream;
char string[50];
read(string);
code(string);
if ((stream = fopen(*(argument_vector + 1), "wb")) != NULL) {
fwrite(string, sizeof(char *), 1, stream);
fclose(stream);
}
} else
if (character == 'S') {
FILE *stream;
if ((stream = fopen(*(argument_vector + 1), "rb")) != NULL) {
char string[50];
fread(string, sizeof(char *), 1, stream);
printf("%s\n", string);
fclose(stream);
}
}
} while (character != 'E');
} else
return printf("Error"), 1;
}
代码函数:
void code(char *string) {
int i = 0;
for(; string[i] != '[=15=]'; i++) {
if ((int)string[i] == 32)
string[i] = ' ';
else
string[i] += 3;
}
string[i + 1] = '[=15=]';
}
读取函数:
void read(char *string) {
printf("Input string: \n");
scanf("\n%[^\n]%*c", string);
}
问题出在这段代码中:
char string[50];
fread(string, sizeof(char *), 1, stream);
printf("%s\n", string);
fread()
读取二进制数据,因此不添加空终止符。
还有,sizeof(char *)
是错误的。您正在读取一个字符串,而不是一个指针。但是 fread()
用于读取固定大小的数据。如果要读取可变大小的字符串,则应指定 1
作为对象的大小,并且最多 49
个对象(您需要为空终止符留出空间)。 fread
returns 它成功读取的对象数,使用它来确定在何处添加空字节。
char string[50];
size_t n = fread(string, 1, 49, stream);
if (n > 0) {
string[n] = '[=11=]';
printf("%s\n", string);
}