我有一个作业,我必须使用一个单词文件(.doc),使用文件系统IO代码读取文件将文件分成两半,并将每一半写入二进制模式下的两个单独文件。我编写了下面的代码,它成功运行并生成了两个文件,甚至文件的大小也是原始文件的一半。但是,当我打开word文件时,它们就会被破坏。这适用于.txt文件,但我的教师说它应该适用于.doc和.zip文件,没有文件损坏。我的代码有问题吗?感谢您的帮助,我非常感谢。
#include <stdio.h>
int main (int argc, char **argv)
{
char *fileName = "1.doc";
char *buffer = "a";
int chunk;
FILE *fd;
fd = fopen (fileName, "rb");
if (fd == NULL);
ferror ("error");
fseek (fd, 0, SEEK_END);
chunk = ftell (fd) / 2;
rewind (fd); //open file, get size, set chunk = to half the file, rewind back to begining of file
fread (buffer, chunk, 1, fd);
fclose (fd); //read the first half of the file into buffer
fd = fopen ("1_1.doc", "wb");
fwrite (buffer, chunk, 1, fd);
fclose (fd); //create new file, write the contents of buffer into it
fd = fopen (fileName, "rb");
fseek (fd, chunk, SEEK_SET);
fread (buffer, chunk, 1, fd);
fclose (fd); //reopen original file, go to half the file, read the remaining half of the file and store in buffer
fd = fopen ("1_2.doc", "wb");
fwrite (buffer, chunk, 1, fd);
fclose (fd); //create a new file, write the second half of the file into it
return 0;
}
我尝试了两种变体
fwrite(buffer, chunk, 1, fd);
和
fwrite(&buffer, chunk, 1, fd);
答案 0 :(得分:1)
你有很多问题,主要是你在不分配内存的情况下使用缓冲区,并试图在read-中写入声明的字符串文字 "a"
的地址只有记忆。
要解决此问题,您必须:
#include <stdlib.h>
...
char *buffer = NULL;
...
chunk = ftell (fd) / 2;
if ((buffer = malloc (chunk * sizeof *buffer)) == NULL) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
您对ferror
的使用不正确,需要FILE *
个参数,而不是char *
:
fd = fopen (fileName, "rb");
if (fd == NULL) {
ferror (fd);
return 1;
}
最后,不要忘记释放不再需要时分配的内存:
free (buffer); /* free allocated memory */
总而言之,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char *fileName = "1.doc";
char *buffer = NULL;
int chunk;
FILE *fd;
/* open file, get size, set chunk = to half the file,
* allocate memory, rewind back to begining of file
*/
fd = fopen (fileName, "rb");
if (fd == NULL) {
ferror (fd);
return 1;
}
fseek (fd, 0, SEEK_END);
chunk = ftell (fd) / 2;
if ((buffer = malloc (chunk * sizeof *buffer)) == NULL) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return 1;
}
rewind (fd);
/* read the first half of the file into buffer */
fread (buffer, chunk, 1, fd); /* you should check return of each read */
fclose (fd);
/* create new file, write the contents of buffer into it */
fd = fopen ("1_1.doc", "wb");
if (fd == NULL) {
ferror (fd);
return 1;
}
fwrite (buffer, chunk, 1, fd); /* you should check return of each write */
fclose (fd);
/* reopen original file, go to half the file, read the
* remaining half of the file and store in buffer
*/
fd = fopen (fileName, "rb");
if (fd == NULL) {
ferror (fd);
return 1;
}
fseek (fd, chunk, SEEK_SET);
fread (buffer, chunk, 1, fd); /* you should check return */
fclose (fd);
/* create a new file, write the second half of the file into it */
fd = fopen ("1_2.doc", "wb");
if (fd == NULL) {
ferror (fd);
return 1;
}
fwrite (buffer, chunk, 1, fd); /* check return */
fclose (fd);
free (buffer); /* free allocated memory */
return 0;
}
输入文件
$ cat 1.doc
Mon Feb 29 10:06:59 CST 2016
Mon Feb 29 10:06:59 CST 2016
Mon Feb 29 10:06:59 CST 2016
Mon Feb 29 10:06:59 CST 2016
示例使用/输出文件
$ ./bin/binread
$ l 1*
-rw-r--r-- 1 david david 116 Apr 6 23:17 1.doc
-rw-r--r-- 1 david david 58 Apr 6 23:18 1_1.doc
-rw-r--r-- 1 david david 58 Apr 6 23:18 1_2.doc
$ cat 1_1.doc
Mon Feb 29 10:06:59 CST 2016
Mon Feb 29 10:06:59 CST 2016
如果您有疑问,请告诉我。
答案 1 :(得分:0)
平均而言,你失去了半个字节。
如果文件大小是偶数,那么文件可以分为两个相等的一半。
如果文件大小为奇数,则一个块必须大一个字节。
size_t length = ftell(fd);
size_t chunk1 = length / 2;
size_t chunk2 = length - chunk1;
你真的需要为大块分配空间; buffer
不能在不写入其他内存的情况下保存超过2个字节,并且这2个字节可能在只读内存中。