fgets()自行初始化变量

时间:2018-08-25 15:38:26

标签: c pointers fgets

我正在编写一些代码,这些代码想从文件中读取数据,解析该数据并将文件中的每个单词存储在一个char数组中。然后,我想使用此数组将其与从单独文件读取的字符串进行比较-这部分您不需要在下面看到。

我的数据正在发生一些非常有趣的事情,我一直在寻找答案,但没有成功。这是代码的简化和简化版本(请用法语输入某些变量的名称):

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

#define maximum 200000

//  CODE

typedef unsigned idx;
typedef char * str;
typedef enum {False, True} bool;

#define max_mots 200000                             
char *mots[max_mots];                               
idx mot_libre = 0;                                  

#define max_refs 16                                 
idx refs[max_mots][max_refs];                       
idx ref_libre[max_mots];                            

void usage(str message) 
{   
    fprintf(stderr, "%s\n", message); 
    exit(1); 
}

str stoplist[max_mots];

void indexe(str ligne, idx ref)                     
{
    printf("stoplist %p: %s\n", &stoplist, *stoplist);
    printf("ligne %p: %s\n", &ligne, ligne);    
}

int main(int argc, const str argv[]) 
{
    int i = 0;
    if (argc < 2) usage("manque le nom du fichier...");
    if (strcmp(argv[2], "-s") == 0){
        FILE * stop = fopen(argv[3], "r");          
        if (! stop) usage("fichier non conforme...");
        char liste[max_mots];
        fgets(liste, maximum, stop);
        str buffer = strtok(liste, " ");
        while (buffer != NULL) {
            printf("%s\n", buffer);
            stoplist[i] = buffer;
            buffer = strtok(NULL, " "); 
            i++;
        }
        fclose(stop);
    } 
    char ligne[maximum];                            
    printf("ligne %p :%s\n", &ligne, ligne);
    FILE * flux = fopen(argv[1], "r");
    if (! flux) { 
        usage("wrong file"); 
    }
    idx x = 0
    while (fgets(ligne, maximum, flux))         
        indexe(ligne, ++x);                             
    fclose(flux);
    return 0;
}

该代码应采用以下格式执行:

[name of the executable] [name of a text file to read from] -s [name of another text file to read from]

第一个文本文件可以是这样的:

hi, I am coding in C.

第二个可能是:

am I in 

代码将要执行的操作是将 stoplist 指针中的每个单词存储在第二个文本文件中的char数组上,并将第一个文本文件的整个字符串存储到 ligne 数组。

执行代码后返回:

am
I
in

ligne [whatever address it has] : am // WHY?! I have not initialized you with this at any point in the code!
stoplist [whatever address it has] : Hi, I am coding in C. // Should be "am"

ligne [whatever address it has] : Hi, I am coding in C.

当我再次调用fgets()分配字符串嗨,我正在用C 编码到 ligne ,同时是 ligne stoplist 将更新为这个新值!从字面上不知道为什么。这两个变量都有不同的地址,正如您在代码中所看到的,所使用的输入也具有不同的名称;两次阅读均以正确的方式进行。

有什么想法吗?我知道这与他们指向相似的事物有关,但是我不明白为什么以及在哪里...

1 个答案:

答案 0 :(得分:1)

这是stoplist初始化的方式:

stoplist[i] = buffer;

buffer来自这里:

str buffer = strtok(liste, " ");

liste是第一个块中的局部变量:

char liste[max_mots];

换句话说,stoplist将指针存储到liste中,但是当您检查stoplist的内容时,liste已经消失了(局部变量在他们方块的结尾)。这就是所谓的“悬空指针”。

您的代码具有未定义的行为。