使用 fwrite 和 fread 的正确方法
correct way to use fwrite and fread
我写了一个程序
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
int r;
char arr[] = "this is the string";
char str[20] = {'[=10=]'};
fp = fopen("fwrite.txt", "w");
fwrite(arr, 1, sizeof(arr), fp);
fseek(fp, SEEK_SET, 0);
r = fread(str, 1, sizeof(arr), fp);
if(r == sizeof(arr))
printf("read successfully\n");
else
{
printf("read unsuccessfull\n");
exit(1);
}
printf("read = %d\n", r);
printf("%s\n", str);
fclose(fp);
return 0;
}
我正在尝试以这种方式阅读,但我做不到。这里有什么问题,是我应该为 fread
放置 &str[i]
和 运行 循环,还是 fread
能够将数据放入 str
?
我越来越乱了,我不明白为什么?
主要问题是你有向后 fseek()
的参数——你需要偏移量 (0
) 在 whence (SEEK_SET
) 之前。第二个问题是您试图从一个只为写入而打开的文件中读取。在这种情况下,一个更小的问题,但通常非常重要,是您没有对 fopen()
调用进行错误检查。 (这个 fopen()
失败的可能性相对较小,但更有趣的事情已经为人所知。)您还应该检查 fwrite()
调用(当然,您已经检查了 fread()
)。
解决所有这些问题可能会导致:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rc = EXIT_SUCCESS;
int r;
const char file[] = "fwrite.txt";
char arr[] = "this is the string";
char str[20] = {'[=10=]'};
FILE *fp = fopen(file, "w+b");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading and writing\n", file);
rc = EXIT_FAILURE;
}
else
{
if (fwrite(arr, 1, sizeof(arr), fp) != sizeof(arr))
{
fprintf(stderr, "Failed to write to file %s\n", file);
rc = EXIT_FAILURE;
}
else
{
fseek(fp, 0, SEEK_SET);
r = fread(str, 1, sizeof(arr), fp);
if (r == sizeof(arr))
{
printf("read successful\n");
printf("read = %d bytes\n", r);
printf("read data [%s]\n", str);
}
else
{
printf("read unsuccessful\n");
rc = EXIT_FAILURE;
}
}
fclose(fp);
}
return rc;
}
示例运行:
$ ./fi37
read successful
read = 19 bytes
read data [this is the string]
$
请注意,这部分有效,因为您将输出字符串末尾的空字节写入文件,然后将其读回。如果文件包含空字节,则它不是真正的文本文件。在不区分二进制文件和文本文件的 Unix 系统上,"w+b"
中的 b
模式并不是真正需要的。如果要将空字节写入 Windows 上的文件,则应使用 b
指示二进制模式。
如果您愿意,可以通过在 main()
函数中不使用单个 return
来减少 'bushiness'(或嵌套深度)。您可以使用 return EXIT_FAILURE;
并避免使用 else
和另一组大括号。显示的代码在文件打开时小心关闭文件。在通用功能中,这很重要。在 main()
中,它不太重要,因为退出进程无论如何都会刷新并关闭打开的文件。
您无法使用 fopen
的 "w"
模式读取文件,请改用 "w+"
。
"r"
- 打开文件进行读取。该文件必须存在。
"w"
- 创建一个 空文件 用于写入。如果已经有同名文件
存在,其内容被删除并且该文件被视为一个新的空文件。
"a"
- 附加到文件。写操作,在末尾追加数据
文件。如果文件不存在,则创建该文件。
"r+"
- 打开文件以同时更新读写。该文件必须存在。
"w+"
- 创建一个用于读写的空文件。
"a+"
- 打开文件进行读取和追加。
我写了一个程序
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
int r;
char arr[] = "this is the string";
char str[20] = {'[=10=]'};
fp = fopen("fwrite.txt", "w");
fwrite(arr, 1, sizeof(arr), fp);
fseek(fp, SEEK_SET, 0);
r = fread(str, 1, sizeof(arr), fp);
if(r == sizeof(arr))
printf("read successfully\n");
else
{
printf("read unsuccessfull\n");
exit(1);
}
printf("read = %d\n", r);
printf("%s\n", str);
fclose(fp);
return 0;
}
我正在尝试以这种方式阅读,但我做不到。这里有什么问题,是我应该为 fread
放置 &str[i]
和 运行 循环,还是 fread
能够将数据放入 str
?
我越来越乱了,我不明白为什么?
主要问题是你有向后 fseek()
的参数——你需要偏移量 (0
) 在 whence (SEEK_SET
) 之前。第二个问题是您试图从一个只为写入而打开的文件中读取。在这种情况下,一个更小的问题,但通常非常重要,是您没有对 fopen()
调用进行错误检查。 (这个 fopen()
失败的可能性相对较小,但更有趣的事情已经为人所知。)您还应该检查 fwrite()
调用(当然,您已经检查了 fread()
)。
解决所有这些问题可能会导致:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rc = EXIT_SUCCESS;
int r;
const char file[] = "fwrite.txt";
char arr[] = "this is the string";
char str[20] = {'[=10=]'};
FILE *fp = fopen(file, "w+b");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading and writing\n", file);
rc = EXIT_FAILURE;
}
else
{
if (fwrite(arr, 1, sizeof(arr), fp) != sizeof(arr))
{
fprintf(stderr, "Failed to write to file %s\n", file);
rc = EXIT_FAILURE;
}
else
{
fseek(fp, 0, SEEK_SET);
r = fread(str, 1, sizeof(arr), fp);
if (r == sizeof(arr))
{
printf("read successful\n");
printf("read = %d bytes\n", r);
printf("read data [%s]\n", str);
}
else
{
printf("read unsuccessful\n");
rc = EXIT_FAILURE;
}
}
fclose(fp);
}
return rc;
}
示例运行:
$ ./fi37
read successful
read = 19 bytes
read data [this is the string]
$
请注意,这部分有效,因为您将输出字符串末尾的空字节写入文件,然后将其读回。如果文件包含空字节,则它不是真正的文本文件。在不区分二进制文件和文本文件的 Unix 系统上,"w+b"
中的 b
模式并不是真正需要的。如果要将空字节写入 Windows 上的文件,则应使用 b
指示二进制模式。
如果您愿意,可以通过在 main()
函数中不使用单个 return
来减少 'bushiness'(或嵌套深度)。您可以使用 return EXIT_FAILURE;
并避免使用 else
和另一组大括号。显示的代码在文件打开时小心关闭文件。在通用功能中,这很重要。在 main()
中,它不太重要,因为退出进程无论如何都会刷新并关闭打开的文件。
您无法使用 fopen
的 "w"
模式读取文件,请改用 "w+"
。
"r"
- 打开文件进行读取。该文件必须存在。
"w"
- 创建一个 空文件 用于写入。如果已经有同名文件
存在,其内容被删除并且该文件被视为一个新的空文件。
"a"
- 附加到文件。写操作,在末尾追加数据
文件。如果文件不存在,则创建该文件。
"r+"
- 打开文件以同时更新读写。该文件必须存在。
"w+"
- 创建一个用于读写的空文件。
"a+"
- 打开文件进行读取和追加。