我必须比较两个文本文件。从<\cipher>
开始,两个文件中都应忽略<\mac>
。这些标签在两个文件中都在同一行。我不知道如何忽略这些线条。
只有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;
}
答案 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}来执行测试以检查您是否已从f2
和MAXL
读取整行。 ,你需要验证读取的最后一个字符是换行符。
注2:关于使用MAXL
- 很少会这样做。什么时候合适?答:当您需要突破(或继续)多个循环时,goto
或break
将无效。选项?您的另一个选择是在断开之前设置一个标志(带有外部循环范围),并在当前循环块结束时立即进行测试,如果设置了标志,则再次中断。 (continue
允许您跨越多个循环 - 您将在许多C库函数中找到它 - 如goto
等。)
测试跳过的线条相同长度
您已经通过测试qsort
和<\cipher>
的第一个字符等于<\mac>
来比较s1
和s2
是否出现在同一行上。要添加确认两个跳过的行的长度相同的测试,只需在跳过测试后测试skip[i]
和strlen
的{{1}},然后设置s1
并突破如果它们的长度不同,则为循环。附加测试可能类似于代码中的以下内容:
s2