我有一个问题,我需要制作一个比较两个文件的程序。 如果在第一个文件中我有:
Milk
Sugar
Eggs
在第二个文件中我有
Vanilla
Soda
Sugar
我想显示两个文件中出现的行。
我没有很多c经验,但我尝试了一些东西。 但我的问题是,如果他们不在同一条线上,我将如何显示Sugar作为输出?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX 100
void equal (char*lineone,char*linetwo){
if(strcmp(lineone,linetwo)==0){
printf("%s",lineone);
}
}
int main(){
FILE *fp1,*fp2;
fp1=fopen("D:/aici/file1.txt","r");
fp2=fopen("D:/aici/file2.txt","r");
char buff[MAX],buff1[MAX];
int i=0;
while((fgets(buff,MAX,fp1)!=NULL)&&(fgets(buff1,MAX,fp2))!=NULL){
//i++;
equal(buff,buff1);
}
}
答案 0 :(得分:1)
你应该做什么(出于性能原因)是将所有单词保存到两个缓冲区中然后进行比较。 但是,您也可以通过稍微改变实现来实现, 只需要将循环分离到一个主循环和一个内循环,这样你就可以得到这样的效果:对于文件1中的每个单词,它将比较文件2中的所有单词,再次,比较时非常慢的方法,只需先保存所有单词然后才相互比较。
void equal (char*lione,char*linetwo){
if(strcmp(lione,linetwo)==0){
printf("%s",lineone);
}
}
int main(){
FILE *fp1,*fp2;
fp1=fopen("D:/aici/file1.txt","r");
fp2=fopen("D:/aici/file2.txt","r");
char buff[MAX],buff1[MAX];
int i=0;
while(fgets(buff,MAX,fp1)!=NULL) {
while(fgets(buff1,MAX,fp2))!=NULL){
//i++;
equal(buff,buff1);
}
rewind(fp2);
}
}
答案 1 :(得分:0)
继续评论,您是否继续使用fgets
(推荐),或者您认识到您也可以使用fscanf
而不必担心从每个字词中移除'\n'
,需要验证程序的每一步。虽然fscanf
一开始可能看起来更容易,但您可能需要了解man fscanf
并确定如何控制每个文件流中将保留未读的'\n'
。
以下是一个简短的示例,继续fgets
,展示了如何测试和删除每个尾随的'\n'
阅读并包含在buff
中的fgets
fgets
1}}。 (以及每个步骤的合理验证)。 (注意:我假设由于你的输入是一个单词,256-char缓冲区就足够了 - 假设 unabridged 字典中最长的单词是28个字符,但你也可以验证是否#include <stdio.h>
#include <string.h>
#define MAXC 256
int main (int argc, char **argv) {
if (argc < 3) { /* validate 2 arguments given */
fprintf (stderr, "error: insufficient input.\n"
"usage: %s file1 file2\n", argv[0]);
return 1;
}
char buf1[MAXC] = "", /* declare buf1 */
buf2[MAXC] = ""; /* declare buf2 */
FILE *f1 = fopen (argv[1], "r"), /* open file 1 */
*f2 = fopen (argv[2], "r"); /* open file 2 */
if (!f1) { /* validate file 1 open for reading */
fprintf (stderr, "file open failed '%s'\n", argv[1]);
return 1;
}
if (!f2) { /* validate file 2 open for reading */
fprintf (stderr, "file open failed '%s'\n", argv[2]);
return 1;
}
while (fgets (buf1, MAXC, f1)) { /* read each word in file 1 */
size_t len1 = strlen (buf1); /* get length */
if (len1 && buf1[len1 - 1] == '\n')
buf1[--len1] = 0; /* overwrite '\n' with nul-byte */
while (fgets (buf2, MAXC, f2)) { /* read each in file 2 */
size_t len2 = strlen (buf2);
if (len2 && buf2[len2 - 1] == '\n')
buf2[--len2] = 0; /* overwrite '\n' with nul-byte */
if (len1 != len2) /* if lengths differ, not equal */
continue; /* get next word from file 2 */
if (strcmp (buf1, buf2) == 0) /* compare strings */
printf ("%s\n", buf1); /* print if equal */
}
rewind (f2); /* rewind f2, clear EOF */
}
fclose (f1); /* close f1 */
fclose (f2); /* close f2 */
return 0;
}
已完整阅读每一行,或者其他字符是否仍然未读)
以下代码要求将每个文件的文件名作为程序的前两个参数。
if (len1 != len2)
(注意:长度检查strcmp
只是一个效率检查,阻止调用strcmp
,除非单词的长度相等。对长度(你已经拥有)的简单比较要少得多比每次$ cat dat/f1cmp.txt
Milk
Sugar
Eggs
$ cat dat/f2cmp.txt
Vanilla
Soda
Sugar
的完整函数调用贵(注意,这是一个非常小的节省,如果你愿意,你可以删除))
输入文件(故意没有POSIX-eol)
数据文件是在没有POSIX行尾的情况下有意创建的,以证明如果你正确处理新行删除,它对结果没有任何影响。
$ ./bin/fgets_cmp_words dat/f1cmp.txt dat/f2cmp.txt
Sugar
示例使用/输出
buf1
仔细研究并完成验证。如果您有任何其他问题,请与我们联系。
要显示单词的不同之处,您只需要修改内部循环。您可以通过循环buf2
和strcmp != 0
中的字符进行简单比较,并在找到第一个差异时停止。您可以继续上述(1)长度不同的两种情况; (2)返回strcmp
,或者你可以在 while (fgets (buf2, MAXC, f2)) { /* read each in file 2 */
size_t len2 = strlen (buf2);
int i = 0;
if (len2 && buf2[len2 - 1] == '\n')
buf2[--len2] = 0; /* overwrite '\n' with nul-byte */
if (len1 != len2) { /* if lengths differ, not equal */
/* locate & output difference */
for (i = 0; buf1[i] == buf2[i]; i++) {}
printf ("%s & %s differ at char %d (%c != %c)\n",
buf1, buf2, i, buf1[i], buf2[i]);
continue; /* get next word from file 2 */
}
if (strcmp (buf1, buf2) == 0) /* compare strings */
printf ("%s\n", buf1); /* print if equal */
else { /* locate & output difference */
for (i = 0; buf1[i] == buf2[i]; i++) {}
printf ("%s & %s differ at char %d (%c != %c)\n",
buf1, buf2, i, buf1[i], buf2[i]);
}
}
的非归零后进行单一测试。
上面对内循环的修改如下所示。我不知道你要找的是什么输出格式,所以我只输出不同的单词并显示单词开始不同的字符(从零开始索引):
$ ./bin/fgets_cmp_wrds dat/f1cmp.txt dat/f2cmp.txt
Milk & Vanilla differ at char 0 (M != V)
Milk & Soda differ at char 0 (M != S)
Milk & Sugar differ at char 0 (M != S)
Sugar & Vanilla differ at char 0 (S != V)
Sugar & Soda differ at char 1 (u != o)
Sugar
Eggs & Vanilla differ at char 0 (E != V)
Eggs & Soda differ at char 0 (E != S)
Eggs & Sugar differ at char 0 (E != S)
示例使用/输出
wizard
仔细看看,如果您有其他问题,请告诉我。