在C语言中检测一个数组的行并查找两个数组的公共字

在C语言中检测一个数组的行并查找两个数组的公共字,c,arrays,loops,scanf,C,Arrays,Loops,Scanf,我有一个名为a1.txt的文件,其中包含这些单词 太棒了 恶毒的 永久性 另一个名为a2.txt的 太棒了 桥 恶意的 这是我用来将文件读入数组的代码,多亏了@moehm 注:void b()与void a()相同,但它改为a2.txt void a(); void b(); char (*a1)[50]; char (*a2)[50]; int n; int main(int argc, char *argv[]) { a(); printf("\n\n");

我有一个名为
a1.txt
的文件,其中包含这些单词

太棒了
恶毒的
永久性

另一个名为
a2.txt

太棒了
桥
恶意的

这是我用来将文件读入数组的代码,多亏了@moehm

注:
void b()
void a()
相同,但它改为
a2.txt

void a();
void b();
char (*a1)[50];
char (*a2)[50];
int n;    


int main(int argc, char *argv[]) {
    a();
    printf("\n\n");
    b();
    int i=0, j=0;
    for (i; i < strlen(*a1); i++)
    {
        for (j; j <strlen(*a2); j++)
        {
            printf("\n%d", strcmp(a1[i], a2[j]));
        }
    }
    return 0;
}

void a(){
FILE *f;          
int i;

f = fopen("a1.txt", "r");
if (f == NULL) {
    fprintf(stderr, "Can't open file\n");
    exit(1);
}

/* first pass */
n = 0;
while (fscanf(f, "%*s") != EOF) n++;   /* star means: scan, but don't store */

a1 = malloc((n + 1) * sizeof(*a1));
if (a1 == NULL) {
    fprintf(stderr, "Allocation failed\n");
    exit(1);
}

/* second pass */
fseek(f, 0, SEEK_SET);
for (i = 0; i < n; i++) {
    fscanf(f, "%49s", a1[i]);
}
*a1[n] = '\0';

/* process words */
for (i = 0; i < n; i++) {
    printf("%s\n",a1[i]);
}}
void a();
无效b();
字符(*a1)[50];
字符(*a2)[50];
int n;
int main(int argc,char*argv[]){
a();
printf(“\n\n”);
b();
int i=0,j=0;
对于(i;i
您正在创建字符指针数组,而不是字符数组。您可能只想将字符指针用作

char *a1;
char *a2;
而不是

a1[50] = calloc(1, lSize +1);

在代码中使用
a1[50]
是不正确的,会导致未定义的行为(包括分段错误)。数组元素从0到49,因此最后一个元素是
a1[49]

此外,您还可以使用
lSize
来读取以下多个字符

for (i=0; i <lSize; i++)
{
    if (fscanf(file, "%c", &a1[i]) == 1){
        printf("%c", a1[i]);
    }
}

对于(i=0;i您似乎对内存分配有一些误解:

  • char*str[50]
    创建一个由50个(未初始化的)char指针组成的数组。也许您需要
    char(*str)[50]
    ,它是指向一个由50个字符组成的数组的指针,您可以向该数组分配内存

  • lSize
    是文件的长度,即字符数。看起来有点像是要计算字数

我将介绍两种将单词读入字符数组的策略

阅读固定大小的单词 此策略使用50的固定字长,如您的示例中所示。它打开文件并分两次读取。第一次是确定字数,第二次是在分配足够的空间后读取实际字数

int main(int argc, char *argv[])
{
    FILE *f;
    char (*str)[50];    /* Pointer to words of max length 49 */
    int n;              /* number of words */
    int i;

    if (argc != 2) {
        fprintf(stderr, "Usage: $fifo file_name.ip\n");
        exit(1);
    }

    f = fopen(argv[1], "r");
    if (f == NULL) {
        fprintf(stderr, "Can't open file\n");
        exit(1);
    }

    /* first pass */
    n = 0;
    while (fscanf(f, "%*s") != EOF) n++;   /* star means: scan, but don't store */

    str = malloc((n + 1) * sizeof(*str));
    if (str == NULL) {
        fprintf(stderr, "Allocation failed\n");
        exit(1);
    }

    /* second pass */
    fseek(f, 0, SEEK_SET);
    for (i = 0; i < n; i++) {
        fscanf(f, "%49s", str[i]);
    }
    *str[n] = '\0';

    /* process words */
    for (i = 0; i < n; i++) {
        printf("%4d: '%s'\n", i, str[i]);
    }
    free(str);

    return 0;
}
这种方法效率更高,但也更复杂。请注意我需要多少变量来跟踪所有内容:分配的大小、实际大小、文本缓冲区的大小。并且我必须处理两个分配的数组

考虑到您想要读取两个文件,将这些变量打包到一个结构中并将每个文件读入这样一个结构是有意义的

结论 这只是从文件中读取单词的许多方法中的两种。这两种方法都很重要,需要您了解如何管理内存

我认为需要学习的最基本的东西之一是指针可以用于许多不同的事情。它可以只指向现有内存,无论是已分配的内存还是自动数组。但它也可以用作已分配内存的句柄;然后它将像数组一样工作,除非您必须
释放
内存ter使用。您不应“移动”此类指针,即更改它们指向的地址


这两种指针在代码中看起来都一样,但您必须知道哪个指针充当什么。

a1[50]=calloc(1,lSize+1)
不起作用。
a1
只有50个元素。你说得对。我现在基本上没有2D数组,我的分配也没用。我该如何解决这个问题?源文件是否按字典顺序排序?如果是这样,你不需要对输入文件进行完全缓冲,而是对每个输入文件使用单行缓冲,遇到一个常用词时,将其转储到输出文件。换句话说,这是一种合并算法,但忽略所有不相同的行,只输出您认为“匹配”的行还有,是否应该忽略大小写敏感度?如果是的话,它实际上会使问题变得更难,而不是更容易。你所说的词典学是指
A到Z
对吗?如果是的话,那么它们是按顺序排序的。你建议我使用
fgets
?是的,大小写敏感度被忽略。这是我所指的。我还没有测试过,但这个想法应该是正确的不言自明。不需要分配。有点像向后合并功能。祝你好运。我一开始就是这么做的,但出于某种原因,我认为这是错误的。然而,这仍然给了我一个1D数组,不是吗?我如何计算其中的字数?@user3601507,答案修复了你将文件读入数组的基本程序。你知道吗我不明白
f=fopen(argv[1],“r”);
如何处理
argv[1]
。本例使用第一个命令行参数
argv[1]
作为文件名;在您的示例中,您可以用
a1.txt替换它
或使用您需要的任何文件名。谢谢。但是,当我尝试使用
strcmp()
比较两个数组时,当我将
a1[0]与a2[0]
进行比较时,它只返回
0
。我将更新我原来的post.Hmmm.
strlen(*a1)
是单词数组
a1
中第一个单词的长度。您需要数组的长度,但不存储该长度。Yopu可以从
a()
b()
返回该长度。此外,如果
a()
b()
只是读取的文件不同,它们应该是一个对不同数据进行操作的函数。无意冒犯,但我的印象是,在解决这个问题之前,您需要更好地掌握基本数据管理和函数。有两个几乎相同的函数是不寻常的;它们通常是“重构”的这是一个随时间而发展的习惯。你现在的问题是C中的字符串是字符数组,因此你的单词数组实际上是数组数组数组。也许你应该玩一下一维数组——自动和分配的——来更好地“感受”它们?
for (i=0; i <lSize; i++)
{
    if (fscanf(file, "%c", &a1[i]) == 1){
        printf("%c", a1[i]);
    }
}
int main(int argc, char *argv[])
{
    FILE *f;
    char (*str)[50];    /* Pointer to words of max length 49 */
    int n;              /* number of words */
    int i;

    if (argc != 2) {
        fprintf(stderr, "Usage: $fifo file_name.ip\n");
        exit(1);
    }

    f = fopen(argv[1], "r");
    if (f == NULL) {
        fprintf(stderr, "Can't open file\n");
        exit(1);
    }

    /* first pass */
    n = 0;
    while (fscanf(f, "%*s") != EOF) n++;   /* star means: scan, but don't store */

    str = malloc((n + 1) * sizeof(*str));
    if (str == NULL) {
        fprintf(stderr, "Allocation failed\n");
        exit(1);
    }

    /* second pass */
    fseek(f, 0, SEEK_SET);
    for (i = 0; i < n; i++) {
        fscanf(f, "%49s", str[i]);
    }
    *str[n] = '\0';

    /* process words */
    for (i = 0; i < n; i++) {
        printf("%4d: '%s'\n", i, str[i]);
    }
    free(str);

    return 0;
}
int main(int argc, char *argv[])
{
    FILE *f;
    char *buf;          /* Buffer that hold the file's contets */
    size_t size;        /* Size of that buffer */
    char **str;         /* Array of pointers to words in that buffer */
    int n;              /* number of words */
    int nalloc;         /* For how many words space is allocated */
    int i;

    if (argc != 2) {
        fprintf(stderr, "Usage: $fifo file_name.ip\n");
        exit(1);
    }

    f = fopen(argv[1], "r");
    if (f == NULL) {
        fprintf(stderr, "Can't open file\n");
        exit(1);
    }

    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, 0, SEEK_SET);

    buf = malloc(size + 1);
    if (buf == NULL) {
        fprintf(stderr, "Allocation failed\n");
        exit(1);
    }

    /* read whoe file */
    fread(buf, 1, size, f);
    buf[size] = '\0';
    fclose(f);

    n = 0;
    nalloc = 0;
    str = NULL;

    for (;;) {
        if (n >= nalloc) {
            /* reallocate */
            nalloc = nalloc * 2;
            if (nalloc == 0) nalloc = 64;
            str = realloc(str, nalloc * sizeof(*str));
            if (str == NULL) {
                fprintf(stderr, "Reallocation failed\n");
                exit(1);
            }
        }
        str[n] = strtok(n ? NULL : buf, " \t\n\r");
        if (str[n] == NULL) break;
        n++;
    }

    /* process words */
    for (i = 0; i < n; i++) {
        printf("%4d: '%s'\n", i, str[i]);
    }
    free(buf);
    free(str);

    return 0;
}