以下是代码:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *f, *fp;
char buff[512];
int buff_size;
int bytes;
fp = fopen("File.txt", "rb");
if (fp == NULL) {
printf("Cannot Open Source File!\n");
exit(1);
}
f = fopen("append.txt", "ab+");
if (f == NULL) {
printf("Cannot Open Target File!\n");
fclose(fp);
exit(1);
}
buff_size = sizeof(buff);
while (bytes = fread(&buff, buff_size, 1, fp) > 0) {
if (bytes > 0)
fwrite(&buff, buff_size, 1, f);
else
break;
printf("Appending...\n\n");
}
rewind(f);
while (bytes = fread(&buff, buff_size, 1, f) > 0)
if (bytes > 0)
printf("%s", buff);
fclose(fp);
fclose(f);
}
所以,它恰好是没有输出任何东西,当我检查文件“append.txt”时它也不包含任何内容。 请注意,源文件“File.txt”不为空。 谁能告诉我它有什么问题?
修改
我通过将buff_size
替换为strlen(buff)
来修复此问题:
bytes = fread(&buff, strlen(buff), 1, f) > 0
和fwrite()
以及fread()
中的select FINALSCORE from
tennismatch join
tennismatch_tennisset on tennismatch.ID = tennismatch_tennisset.TennisMatch_ID and tennismatch.ID = 1 join
tennisset on tennismatch_tennisset.mapOfSets_ID = tennisset.ID
相同。
有人可以解释为什么会这样吗?
答案 0 :(得分:2)
char buff[512];
int buff_size;
// [...]
bytes = fread(&buff, buff_size, 1, fp)
这将尝试读取一个512字节的块。返回值是读取的块数,因此它不是字节。但抛开这一点,如果你的文件短于512字节,这将不会读取任何。
你想要的是读取512次1字节,然后你将得到字节数,所以交换buff_size
和1
的位置。
附注:
如果你在循环条件中正确检查,如:
while ((bytes = fread(buff, 1, buff_size, fp)) > 0 )
对if (bytes > 0)
的额外检查是多余的。
写入时,您只想写入实际读取的字节数:
fwrite(buff, 1, bytes, f);
对于尺码,始终使用size_t
- int
很可能是错误的:
size_t buff_size;
size_t bytes;
打印buff
printf("%s", )
是未定义的行为,因为在{{1}读取数据后没有添加'\0'
个字节}}。 C字符串必须以fread()
结尾。如果'\0'
读取的数据偶然不包含fread()
,'\0'
将会读取并使用未初始化的数据,甚至可能超出printf()
的范围。< / p>
答案 1 :(得分:1)
Felix Palmen在您的代码中列出了许多问题,您的修复完全错误,因为buff
甚至没有空终结符。
这是一个更好的版本:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *f, *fp;
char buff[512];
size_t bytes;
fp = fopen("File.txt", "rb");
if (fp == NULL) {
fprintf(stderr, "Cannot open source file!\n");
exit(1);
}
f = fopen("append.txt", "ab+");
if (f == NULL) {
fprintf(stderr, "Cannot open target file!\n");
fclose(fp);
exit(1);
}
while ((bytes = fread(buff, 1, sizeof buff, fp)) != 0) {
if (fwrite(buff, 1, bytes, 1, f) != bytes) {
fprintf(stderr, "Error writing to the target file\n");
break;
}
printf("Appending...\n\n");
}
rewind(f);
while ((bytes = fread(buff, 1, sizeof buff, f)) != 0) {
printf("%.*s", (int)bytes, buff);
}
fclose(fp);
fclose(f);
return 0;
}
答案 2 :(得分:1)
bytes = fread(&buff, buff_size, 1, fp) > 0
看看C Precedence Chart。运算符>
高于=
,因此fread
的返回值将与零进行比较,然后该比较的结果将存储在bytes
中。你打算写这个
(bytes = fread(&buff, buff_size, 1, fp)) > 0
答案 3 :(得分:1)
给定固定文件名,这是我的问题解决方案。如果是我自己的代码,它会将文件名作为参数。
#include <stdio.h>
int main(void)
{
const char src_file[] = "File.txt";
FILE *fp = fopen(src_file, "rb");
if (fp == NULL)
{
fprintf(stderr, "Cannot Open Source File '%s'!\n", src_file);
return(1);
}
const char tgt_file[] = "append.txt";
FILE *f = fopen(tgt_file, "ab+");
if (f == NULL)
{
fprintf(stderr, "Cannot Open Target File '%s'!\n", tgt_file);
fclose(fp);
return(1);
}
char buff[512];
int bytes;
while ((bytes = fread(buff, sizeof(char), sizeof(buff), fp)) > 0)
{
fwrite(buff, sizeof(char), bytes, f);
printf("Appending...\n\n");
}
rewind(f);
while ((bytes = fread(buff, sizeof(char), sizeof(buff), f)) > 0)
printf("%.*s", bytes, buff);
fclose(fp);
fclose(f);
return 0;
}
有各种各样的修复方法,其中大多数都是在评论的某些地方明确表达的。
我将文件名设置为数组,以便可以在fopen()
和错误消息中使用该名称,这些消息打印到stderr
,而不是stdout
。这对于通用代码中的其他用户很有帮助。如果文件名来自命令行参数,则很简单。
对fread()
的调用是固定的,以便报告字节数,而不是512字节块的数量(将为0或1)。这涉及将大小/计数参数的顺序反转为fread()
。传递缓冲区而不是缓冲区的地址。
正确捕获读取的字节数。
读取的字节数用于控制fwrite()
的大小。
读取的字节数用于控制printf()
打印的字节数。
我不喜欢C99及更高版本中的特殊规则允许main()
- 但只有main()
- 默认返回0。 AFAIAC,它是一个定义为返回int
的函数;它应该返回int
。但是,还有其他人不同意。