无法在main()和函数(列表)之间传递值

问题描述 投票:0回答:3

我在一个学校项目中“工作”,需要使用带有字符*和其他一些变量的链表。事情是:

我正在使用一个子函数来打开,读取和存储List中的数据,但是无法访问它上面的字符串,我的意思是,可以看到其他信息只是那个...

void main()
{
    Palavra* P = lerPalavras();
    printf ("%s", P->c);               //Was just testing in this ...
}

子功能

Palavra* lerPalavras ()               //Just ignore what is going on here in the code, the problem is when I call it, within the function the output works just fine, but when I pass to main it's just not working at all. Thanks
{
    char linha [50];
    Palavra* P = NULL;
    Palavra* pv = NULL;
    FILE* ficheiro = fopen ("keywords.txt", "r");

    if(ficheiro == NULL)
    {
        printf ("Abertura do Ficheiro 'keywords.txt' Falhou!");
        return NULL;
    }   
    while (fgets (linha, sizeof (linha), 
    {
        if (linha [strlen(linha) - 1] != '\n')
            linha [strlen(linha)] = '\0';
        else
            linha [strlen(linha) - 1] = '\0';
        pv = CriaKW ();
        pv->c = linha;
        pv->tam = strlen (linha);
        P = insertKW (P, pv);
    }
    fclose (ficheiro);
    return (P);
}

结构“消息”

typedef struct KW
{
    char* c;
    struct KW* nseg;
    int ID;
    long int tam;
} Palavra;

功能“CriaKW”

Palavra* CriaKW ()                                          
{
    Palavra * pv = (Palavra*) malloc (sizeof (Palavra));
    return (pv);
}

功能“insertKW”

Palavra* insertKW (Palavra* P, Palavra* pv)
{
    pv->nseg = NULL;
    if (P == NULL)                      //Ver se a Lista está vazia
        return (pv);
    Palavra* p = P;                     //Variável Auxiliar para não perder a cabeça da Lista
    while (p->nseg != NULL)             //Ver se a "caixa" tem seguinte
        p = p->nseg;                    //Correr a Lista
    p->nseg = pv;
    return (P);
}
c string list singly-linked-list
3个回答
0
投票

数组linha是函数的本地对象

Palavra* lerPalavras ()
{
    char linha [50];
    //...

具有自动存储持续时间,退出该功能后,它将不会存活,并且可能被程序的其他对象覆盖,甚至无法访问。

在任何情况下,每个节点的指针pv->c都以这种方式初始化

pv->c = linha;

退出函数后将具有无效值。

您应该动态分配此指针指向的内存,并将原始字符串复制到分配的内存中。

例如

linha[ strcspn( linha, "\n" ) ] = '\0';
size_t n = strlen( linha );

pv->c = malloc( n + 1 );
strcpy( pv->c, linha );
pv->tam = n;

此外,您还需要记住在删除列表节点时释放为字符串分配的内存。

考虑到更好的是代替long int类型使用size_t类型为数据成员tam,因为通常没有必要类型size_t等同于类型long int虽然标准函数strlen和其他字符串函数使用类型size_t.

size_t tam;

0
投票

由于这条线有两个问题:pv->c = linha;

  1. 它正在保存一个指向它返回的结构中的局部变量的指针。当函数返回时,该变量被销毁,因此指针不再有效。
  2. 您为每个读取的行使用相同的linha变量。所以即使变量没有被破坏,所有Palavra结构都会有文件的最后一行。

您需要复制该行以保存它。将该行更改为:

pv->c = strdup(linha);

strdup()是一个POSIX函数,而不是标准C.如果这是对你的代码的限制,你应该很容易使用malloc()strcpy()自己编写。

顺便说一句,这条线是不需要的:

        linha [strlen(linha)] = '\0';

由于strlen()通过找到\0角色的位置来工作,这只是将该角色设置为已有的角色。将包含此内容的if更改为:

if (linha[strlen(linha)-1] == '\n') {
    linha[strlen(linha)-1] = '\0';
}

0
投票

感谢大家,我是新来的,但你们都试着帮忙!非常感谢!

这段代码是:pv-> c = strdup(linha);

© www.soinside.com 2019 - 2024. All rights reserved.