【问题标题】:Check if 2 files content is equal检查2个文件内容是否相等
【发布时间】:2021-12-30 02:44:34
【问题描述】:

被要求获取 2 个文件,并带有一个文件描述符 - 检查两者上的每个字符并查看是否相等,如果文件 n.1 中的 1 个字符与文件 n.2 不同 - 返回 1,如果两个文件都有相同的内容 - 返回 2,如果除了我提到的之外还有任何情况(问题) - 返回 0/1。

我的问题是程序每次都返回 2,如果 2 个文件具有以下内容:“abcd”,或者即使一个文件具有:“abcd”而另一个文件具有:“abcg”/“abc”。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <errno.h>


int main(int argc, char * argv[]){
    if(argc != 3)
        return 0;
    
    int fd1 = open(argv[1], O_RDONLY);
    int fd2 = open(argv[2], O_RDONLY);
    
    if(fd1 == -1 || fd2 == -1)
        return 0;
    
    char c1, c2;
    
    if(read(fd1, &c1, 1) == 0 || read(fd2, &c2, 1) == 0)
        return 1;
    if(c1 != c2)
            return 1;
    
    while(read(fd1, &c1, 1) == 0 || read(fd2, &c2, 1) == 0){
        if(c1 != c2)
            return 1;
    }
    
    return 2;
}

在此先感谢各位,对于语法错误,我深表歉意,英语不是我的主要语言。

【问题讨论】:

  • 解释一下while:while(at_end_of_file(fd1) || at_end_of_file(fd2))——如果文件长于一个字符,则根本不会进入循环。
  • @dratenik 嘿,感谢您的快速回复:)您能否进一步解释一下?我对此很陌生
  • 没有理由单独检查第一个字符,折腾if read...。你需要重新思考这个循环。
  • 此外,逐字节读取文件的效率非常低。您应该读取更大的块(一次可能 64 K)并比较这些块,例如与 memcmp
  • @Jabberwocky ,我的老师告诉我们检查每个字符来完成这项任务,但我仍然不明白为什么程序只返回 2,而不是如果文件不同则返回 1他们拥有的内容:/

标签: c system-calls file-descriptor


【解决方案1】:

这是您需要的伪代码,假设您要逐字节读取文件:

  repeat
    read one byte from file 1
    read one byte from file 2
    
    if you did not read the same number of bytes from both files,
    the files are different and you can stop

    if the number of bytes read is 0, you're at the end of the files,
    the files have the same content and you can stop

    if bytes read are different, the file are different and you can stop

  end of repeat

提示:read 函数返回读取的字节数,在您的情况下,如果字节被成功读取,则返回 1,如果是文件末尾,则返回 0。

【讨论】:

  • @chux-ReinstateMonica 感谢编辑
  • 如果我进入 while 循环并且在第一次操作时两个起始字符的值不同(c1 != c2),我如何返回 1?我在哪里可以返回 1?因为现在,如果它发生 - 它会返回 2,这就是为什么我在进入 while 循环之前检查了第一个字符。 (顺便编辑了代码:))
  • @RyanOtweeng 在答案到达后更改问题是糟糕的堆栈溢出礼仪。您正在创建一个移动目标。请还原代码。
  • 很抱歉,对规则很陌生。
  • @RyanOtweeng 不要区别对待第一个字符。只需通过伪代码申请即可。
猜你喜欢
  • 2010-11-16
  • 2015-07-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
相关资源
最近更新 更多