比较c中的两个文件;跳过具有特定单词的行

时间:2015-06-29 04:00:06

标签: c

我必须比较两个文本文件。从<\cipher>开始,两个文件中都应忽略<\mac>。这些标签在两个文件中都在同一行。我不知道如何忽略这些线条。

  1. 必须跳过这两个文件中的行标记。
  2. 比较线条和每个字符。
  3. 检查每个文件的文件/大小的结尾。
  4. 只有no.1必须解决,并且在下面的代码中已经解决了no.2和no.3。

    示例文件:

    TextFile 1

    <\date> 16th December 2016 
    <\name> thiri
    <\cipher> a girl
    <\age> 22
    <\mac> 2316
    

    TextFile 2

    <\date> 16th December 2016
    <\name> thiri
    <\cipher> female
    <\age> 22
    <\mac> 1234
    

    我的代码如下所述:

    int main (int argc, const char *argv [ ])
    {
        //Compare Text- Compare two files in details(but cannot ignore such lines)
    
        FILE *fpr1, *fpr2;
        int ch1, ch2;
        char fname1[80], fname2[80];
    
        printf("Enter file-directory:");
        scanf("%s",fname2);
    
        fpr1 = fopen("/Users/khinthirihtet/Documents/PSKC_Testing/PSKC_Testing/narme.txt", "r");
        fpr2 = fopen(fname2, "r");
    
        if (fpr1 == NULL)
        {
            printf("Cannot open REFERENCE_FILE in %s", fname1);
            exit(1);
        }
        else if (fpr2 == NULL)
        {
            printf("Cannot open your file in %s to check format", fname2);
            exit(1);
        }
        else
        {
            while ((ch1 != EOF) && (ch2 != EOF) && (ch1 == ch2))
            {
                ch1 = getc(fpr1);
                ch2 = getc(fpr2);
            }    
            if (ch1 == ch2)
                printf("Your File is matched.");
            else if (ch1 != ch2)
                printf("Your File is NOT matched,please verify again!");
    
            fclose(fpr1);
            fclose(fpr2);
        }
        return 0;
    }
    

2 个答案:

答案 0 :(得分:1)

如果特殊单词位于每行的前面,这会更容易一些,但一般解决方案都是相同的。创建一个函数来从文件中读取一行并返回一个字符串。如果函数找到一条带有一个特殊字符串的行,那么它将完成该行的读取,但随后丢弃该文本并重新开始读取一行。为您的每个文件调用此函数并比较它们的结果。重复,直到您到达一个或两个文件的末尾。

答案 1 :(得分:0)

在作业中学习有两个以上的微妙机会。第一个是正确地转义跳过术语,因此可以进行有效的比较。通过这一点,实际上只需要两个函数来进行比较:strncmp(检查跳过术语)和strcmp(检查剩余行)。

除了检查行的内容之外,还需要检查一个文件是否比另一个文件更长(包含更多行)。一种快速方法是检查同时读取每个文件的同时读取EOF。如果一个到达EOF或在另一个之前返回NULL,那么文件也会有所不同。 (您不能依赖于大小检查,因为跳过的行的内容可能会有所不同。)

将这些放在一个简短的例子中,进行比较的一种方法是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXL 64

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

    if (argc < 3 ) {
        fprintf (stderr, "error: insufficient input, usage: %s file1 file2\n", 
                argv[0]);
        return 1;
    }

    char *skip[] = { "<\\cipher>", "<\\mac>" }; /* skip terms       */
    char s1[MAXL] = {0}, s2[MAXL] = {0};        /* lines from files */
    unsigned char differ = 0;                   /* differ flag      */
    size_t skipsz = sizeof skip/sizeof *skip;   /* elements in skip */
    size_t i = 0;   /* general variable */
    FILE *f1, *f2;  /* file pointers    */

    /* open both files or exit */
    if (!((f1 = fopen (argv[1], "r")) && (f2 = fopen (argv[2], "r")))) {
        fprintf (stderr, "error: file open failure.\n");
        return 1;
    }

    /* read a line from each file */
    for (;;)
    {
        char *p1 = fgets (s1, MAXL, f1);    /* check return of read */
        char *p2 = fgets (s2, MAXL, f2);

        if ((!p1 && p2) || (p1 && !p2)) {
            differ = 1;     /* if one file is longer than the other */
            break;
        }
        else if (!(p1 || p2))
            break;          /* if both return NULL at EOF, break    */

        for (i = 0; i < skipsz; i++)    /* skip if matches skip[i]  */
            if (strncmp (s1, skip[i], strlen (skip[i])) == 0 ||
                strncmp (s2, skip[i], strlen (skip[i])) == 0 )
                goto skipping;          /* yes -- it lives....      */

        if (strcmp (s1, s2)) {          /* compare lines & set flag */
            differ = 1;
            break;
        }
        skipping:;
    }

    fclose (f1);    /* close files */
    fclose (f2);

    if (differ)     /* print results */
        printf ("\n files '%s' and '%s': differ\n\n", argv[1], argv[2]);
    else
        printf ("\n files '%s' and '%s': match\n\n", argv[1], argv[2]);

    return 0;
}

<强>输出

$ ./bin/cmpf1f2 dat/tf1.txt dat/tf2.txt

 files 'dat/tf1.txt' and 'dat/tf2.txt': match

注意:如果使用MAXL(最大行)define设置初始行大小。它可以根据需要进行调整。接下来,您还应该通过检查行长度是否小于f1以及它是否等于{{1}来执行测试以检查您是否已从f2MAXL读取整行。 ,你需要验证读取的最后一个字符是换行符。

注2:关于使用MAXL - 很少会这样做。什么时候合适?答:当您需要突破(或继续)多个循环时,gotobreak将无效。选项?您的另一个选择是在断开之前设置一个标志(带有外部循环范围),并在当前循环块结束时立即进行测试,如果设置了标志,则再次中断。 (continue允许您跨越多个循环 - 您将在许多C库函数中找到它 - 如goto等。)

测试跳过的线条相同长度

您已经通过测试qsort<\cipher>的第一个字符等于<\mac>来比较s1s2是否出现在同一行上。要添加确认两个跳过的行的长度相同的测试,只需在跳过测试后测试skip[i]strlen的{​​{1}},然后设置s1并突破如果它们的长度不同,则为循环。附加测试可能类似于代码中的以下内容:

s2