C 中的 fgetc 和 fputc
fgetc and fputc in C
我正在尝试从一个文件的开头复制 5 个字节并将它们放入另一个文件的开头。然而,他们并没有准确地复制。我认为问题出在 fputc 和 fgetc 中,但不确定是什么...
bmpFile = fopen("frog.bmp", "rb");
encodedFile = fopen("encodedFrog.bmp", "rwb");
for (int i=0; i<5; i++){
fputc(fgetc(bmpFile), encodedFile); //copy that byte, unchanged into the output
}
//close and open both files, read the first 5bytes back;
fclose(bmpFile);
fclose(encodedFile);
bmpFile = fopen("frog.bmp", "rb");
encodedFile = fopen("encodedFrog.bmp", "rwb");
for (int i=0; i<5; i++){
unsigned int actual = fgetc(bmpFile);
unsigned int value = fgetc(encodedFile);
printf("actual: %d \tvalue: %d\n", actual, value);
}
结果是:
actual: 66 value: 66
actual: 77 value: 77
actual: 54 value: 134
actual: 115 value: 68
actual: 20 value: 17
谢谢
"rwb"
不是有效的 fopen
模式。您可能想使用
fopen("encodedFrog.bmp", "r+b");
这将以二进制模式打开现有文件进行输入和输出。如果文件不存在,你应该使用 "w+b"
.
fopen("encodedFrog.bmp", "w+b");
这将以二进制模式打开一个用于输入和输出的新文件。
此外,正如@amdixon 提到的,您应该使用 rewind
,而不是重新打开文件,这会将流位置重置为开头。
修复 fopen
问题后,您可能需要查看 fread
和 fwrite
,它们可以对二进制 read/writes 提供一些额外的错误检查。
虽然二进制 reading/writing 一次一个字符没有错,但对于二进制文件流 input/output 你有额外的功能 fread
和 fwrite
允许您读取和写入特定数量的字节(或任何其他 size
值,例如 int
,等等)。基本语法是:
size_t fread (void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite (const void *ptr, size_t size, size_t nmemb,
FILE *stream);
所以代替:
for (int i=0; i<5; i++){
fputc(fgetc(bmpFile), encodedFile);
}
您可以使用 fread
和 fwrite
来验证读取和写入的 'size'
元素的数量:
unsigned char buf[5] = {0};
if (fread (buf, 1, 5, bmpFile) == 5) {
if (fwrite (buf, 1, 5, encodedFile) != 5)
fprintf (stderr, "error: fwrite failed for encodedFile.\n");
}
else
fprintf (stderr, "error: fread failed for bmpFile.\n");
一个简单的例子可能是:
#include <stdio.h>
int main (int argc, char **argv) {
FILE *in, *out;
unsigned char buf[8] = {0};
unsigned char chr[8] = {0};
size_t i;
if (argc < 3) {
fprintf (stderr, "error: insufficient input. prog infile outfile (binary cp)\n");
return 1;
}
if (!(in = fopen (argv[1], "r+b")) || !(out = fopen (argv[2], "w+b"))) {
fprintf (stderr, "error: file open failed.\n");
return 1;
}
if (fread (buf, 1, 5, in) == 5) {
if (fwrite (buf, 1, 5, out) != 5)
fprintf (stderr, "error: fwrite failed for encodedFile.\n");
}
else
fprintf (stderr, "error: fread failed for bmpFile.\n");
rewind (in);
rewind (out);
if (fread (buf, 1, 5, in) != 5 || fread (chr, 1, 5, out) != 5) {
fprintf (stderr, "error: read after rewind failed.\n");
return 1;
}
fclose (in);
fclose (out);
for (i = 0; i < 5; i++)
printf (" actual : %3hhu value : %3hhu\n", buf[i], chr[i]);
putchar ('\n');
return 0;
}
Example/Output
$ ./bin/freadfwrite bin/xpathfname bin/ytestout
actual : 127 value : 127
actual : 69 value : 69
actual : 76 value : 76
actual : 70 value : 70
actual : 2 value : 2
我正在尝试从一个文件的开头复制 5 个字节并将它们放入另一个文件的开头。然而,他们并没有准确地复制。我认为问题出在 fputc 和 fgetc 中,但不确定是什么...
bmpFile = fopen("frog.bmp", "rb");
encodedFile = fopen("encodedFrog.bmp", "rwb");
for (int i=0; i<5; i++){
fputc(fgetc(bmpFile), encodedFile); //copy that byte, unchanged into the output
}
//close and open both files, read the first 5bytes back;
fclose(bmpFile);
fclose(encodedFile);
bmpFile = fopen("frog.bmp", "rb");
encodedFile = fopen("encodedFrog.bmp", "rwb");
for (int i=0; i<5; i++){
unsigned int actual = fgetc(bmpFile);
unsigned int value = fgetc(encodedFile);
printf("actual: %d \tvalue: %d\n", actual, value);
}
结果是:
actual: 66 value: 66
actual: 77 value: 77
actual: 54 value: 134
actual: 115 value: 68
actual: 20 value: 17
谢谢
"rwb"
不是有效的 fopen
模式。您可能想使用
fopen("encodedFrog.bmp", "r+b");
这将以二进制模式打开现有文件进行输入和输出。如果文件不存在,你应该使用 "w+b"
.
fopen("encodedFrog.bmp", "w+b");
这将以二进制模式打开一个用于输入和输出的新文件。
此外,正如@amdixon 提到的,您应该使用 rewind
,而不是重新打开文件,这会将流位置重置为开头。
修复 fopen
问题后,您可能需要查看 fread
和 fwrite
,它们可以对二进制 read/writes 提供一些额外的错误检查。
虽然二进制 reading/writing 一次一个字符没有错,但对于二进制文件流 input/output 你有额外的功能 fread
和 fwrite
允许您读取和写入特定数量的字节(或任何其他 size
值,例如 int
,等等)。基本语法是:
size_t fread (void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite (const void *ptr, size_t size, size_t nmemb,
FILE *stream);
所以代替:
for (int i=0; i<5; i++){
fputc(fgetc(bmpFile), encodedFile);
}
您可以使用 fread
和 fwrite
来验证读取和写入的 'size'
元素的数量:
unsigned char buf[5] = {0};
if (fread (buf, 1, 5, bmpFile) == 5) {
if (fwrite (buf, 1, 5, encodedFile) != 5)
fprintf (stderr, "error: fwrite failed for encodedFile.\n");
}
else
fprintf (stderr, "error: fread failed for bmpFile.\n");
一个简单的例子可能是:
#include <stdio.h>
int main (int argc, char **argv) {
FILE *in, *out;
unsigned char buf[8] = {0};
unsigned char chr[8] = {0};
size_t i;
if (argc < 3) {
fprintf (stderr, "error: insufficient input. prog infile outfile (binary cp)\n");
return 1;
}
if (!(in = fopen (argv[1], "r+b")) || !(out = fopen (argv[2], "w+b"))) {
fprintf (stderr, "error: file open failed.\n");
return 1;
}
if (fread (buf, 1, 5, in) == 5) {
if (fwrite (buf, 1, 5, out) != 5)
fprintf (stderr, "error: fwrite failed for encodedFile.\n");
}
else
fprintf (stderr, "error: fread failed for bmpFile.\n");
rewind (in);
rewind (out);
if (fread (buf, 1, 5, in) != 5 || fread (chr, 1, 5, out) != 5) {
fprintf (stderr, "error: read after rewind failed.\n");
return 1;
}
fclose (in);
fclose (out);
for (i = 0; i < 5; i++)
printf (" actual : %3hhu value : %3hhu\n", buf[i], chr[i]);
putchar ('\n');
return 0;
}
Example/Output
$ ./bin/freadfwrite bin/xpathfname bin/ytestout
actual : 127 value : 127
actual : 69 value : 69
actual : 76 value : 76
actual : 70 value : 70
actual : 2 value : 2