c - fgets() 自行初始化变量

标签 c pointers fgets

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

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

#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 数组中,并将第一个文本文件的整个字符串存储到 对齐数组。

代码执行后返回:

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() 将字符串 Hi, I am coding in C 分配给 ligne 时,ligne>stoplist 将更新为这个新值!字面上不知道为什么。两个变量都有不同的地址,正如您在代码中看到的,使用的输入也有不同的名称;两次阅读 session 都以正确的方式结束。

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

最佳答案

stoplist 是这样初始化的:

stoplist[i] = buffer;

buffer 来自这里:

str buffer = strtok(liste, " ");

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

char liste[max_mots];

换句话说,stoplist 将指针存储到 liste 中,但是当您检查 stoplist 的内容时,liste 已经消失(局部变量在其 block 的末尾被销毁)。这被称为“悬挂指针”。

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

关于c - fgets() 自行初始化变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52018773/

相关文章:

c - cygwin 和 eclipse 的 sockets.h 问题

c++ - gcc和g++之间-Wconversion的区别

c - C 中数字的隐式类型

c - 如何在C中分配多维数组所需的内存?

c - scanf 之后 fgets 不起作用

C 不为新的 char 数组分配内存

pointers - Rust 中的指针转换是否与 C++ 中的 reinterpret_cast 具有相同的行为?

无法访问结构体中的结构体数组中的成员变量

c - 将 char *[] 数组传递到采用参数 const char ** 的函数中

C - 带有嵌套 fgets 循环的 fork 和管道