gpt4 book ai didi

在C中以相反的顺序将字节从一个文件复制到另一个文件

转载 作者:行者123 更新时间:2023-11-30 15:10:25 25 4
gpt4 key购买 nike

检查 answer here 后,并在我的环境中运行它,我发现该代码仍然遇到与我的代码相同的问题。这个问题是,每当我有一个与此类似的输入文件时......

 FILE A                 
|---------------------|
| ABCDE |
| abcde |
|---------------------|

我在目标文件中生成了额外的换行符空格。

 FILE B                 
|---------------------|
| edcba |
| |
| EDCBA |
|---------------------|

调试代码后,我可以看到“\n”被复制到目标文件两次,我想了解 lseek 为何这样做。

附件是我的代码。有问题的关键部分位于 do/while 循环中。我非常确定我的思考过程是正确的,正如 answer 中的代码一样我查到的结果会输出完全相同的结果。

#define CHAR_SIZE 2048 
#define BUFF_SIZE 1
#define PERMS 0666


int main(int argc, char* argv[]){
if (argc < 3) {
return 1;
printf ("ERROR: not enough arguments\n");
}
int src_file = 0; int dest_file = 0;
int n = -1;
if((src_file=open(argv[1],O_RDONLY)) < -1) return 1;
if((dest_file = creat(argv[2], PERMS)) < -1) return 1;
printf ("The filesize is: %d\n", lseek(src_file, (off_t) 0, SEEK_END));
char buffer[BUFF_SIZE];
lseek (src_file,n--,SEEK_END);
do {
read(src_file,buffer,BUFF_SIZE);
printf ("%s", buffer);
write(dest_file,buffer,BUFF_SIZE);
}while (lseek (src_file,n--,SEEK_END) > -1);
printf("\n");
return 0;

}

最佳答案

您有很多问题。额外的换行符来自于 POSIX 将行尾定义为换行符(尽管并非所有文件都符合)。因此,要摆脱多余的换行符,您需要:

int n = -2;

而不是

int n = -1;

(显式读取 POSIX 行尾并将其写入输出文件)

您的其他问题是您不知道文件打开是否失败,因为您错误地检查了返回值:

// if ((src_file = open (argv[1],O_RDONLY)) < -1) return 1;
// if ((dest_file = creat (argv[2], PERMS)) < -1) return 1;

失败时返回-1。因此你需要:

if ((src_file = open (argv[1],O_RDONLY)) == -1) return 1;
if ((dest_file = creat (argv[2], PERMS)) == -1) return 1;

接下来,您的缓冲区将不再保存字符串。您至少需要一个 2-char 数组来保存 1-char 加上 nul-termination 字符。以下内容将不起作用:

#define BUFF_SIZE 1
...
char buffer[BUFF_SIZE];
...
printf ("%s", buffer);

您已向 printf 发送了一个非终止字符。如果您在启用警告的情况下进行编译(例如 -Wall -Wextra),您就会知道,因为编译器会警告您(即使没有正确的警告标志,它也可能会这样做,具体取决于你的编译器)。至少要完成上述工作,您需要:

#define BUFF_SIZE 2

并且您必须在调用 printf 之前确保nul-terminate buffer。您可以通过以下方式实现:

char buffer[BUFF_SIZE] = "";
...
read (src_file, buffer, BUFF_SIZE - 1);
buffer[1] = 0;
printf ("%s", buffer);
write (dest_file, buffer, BUFF_SIZE - 1);

(您应该检查 readwrite 的返回,以验证您正在读取/写入您认为的字节数...)

将更正放在一起(并表明您可以完全消除缓冲区并简单地使用 int 作为 buf char),您可以执行以下操作:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define CHAR_SIZE 2048
#define BUFF_SIZE 2
#define PERMS 0666

int main(int argc, char **argv) {

if (argc < 3) {
return 1;
printf ("ERROR: not enough arguments\n");
}

int src_file = 0;
int dest_file = 0;
int n = -2;
int nl = '\n'; /* explicit newline when writing in reverse */

// if ((src_file = open (argv[1],O_RDONLY)) < -1) return 1;
// if ((dest_file = creat (argv[2], PERMS)) < -1) return 1;
if ((src_file = open (argv[1],O_RDONLY)) == -1) return 1;
if ((dest_file = creat (argv[2], PERMS)) == -1) return 1;

printf ("The filesize is: %ld\n", lseek(src_file, (off_t) 0, SEEK_END));

lseek (src_file, n--, SEEK_END);
#ifdef WBUFCHAR
int bufchar;
do { /* validate both read and write */
if (read (src_file, &bufchar, BUFF_SIZE - 1) == 0) {
fprintf (stderr, "error: read failure.\n");
return 1;
}
putchar (bufchar);
if (write (dest_file, &bufchar, BUFF_SIZE - 1) == 0) {
fprintf (stderr, "error: write failure.\n");
return 1;
}
} while (lseek (src_file, n--, SEEK_END) > -1);
#else
char buffer[BUFF_SIZE];
do { /* validate both read and write */
if (read (src_file, buffer, BUFF_SIZE - 1) == 0) {
fprintf (stderr, "error: read failure.\n");
return 1;
}
buffer[1] = 0; /* nul-terminate */
printf ("%s", buffer);
if (write (dest_file, buffer, BUFF_SIZE - 1) == 0) {
fprintf (stderr, "error: write failure.\n");
return 1;
}
} while (lseek (src_file, n--, SEEK_END) > -1);
#endif
/* explicity write the newline you removed earlier */
if (write (dest_file, &nl, BUFF_SIZE - 1) == 0) {
fprintf (stderr, "error: write failure.\n");
return 1;
}
putchar ('\n');
return 0;
}

注意:正常编译以使用您的缓冲区。使用 -DWBUFCHAR 编译以使用 bufchar 代码。

示例编译和输出

$ cat testabcde.txt
ABCDE
abcde

$ gcc -Wall -Wextra -Ofast -o bin/extranl extranl.c

$ ./bin/extranl testabcde.txt testrev.txt
The filesize is: 12
edcba
EDCBA

$ cat testrev.txt
edcba
EDCBA

$ gcc -Wall -Wextra -Ofast -DWBUFCHAR -o bin/extranlwbc extranl.c

$ ./bin/extranlwbc testabcde.txt testrevwbc.txt
The filesize is: 12
edcba
EDCBA

$ cat testrevwbc.txt
edcba
EDCBA

尝试一下,如果您还有其他问题,请告诉我。

关于在C中以相反的顺序将字节从一个文件复制到另一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36169834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com