无法在 main() 和函数(列表)之间传递值
Can't pass values between main() and a function (lists)
我 "working" 在一个学校项目中需要使用带有 chars* 和其他一些变量的链表。事情是:
我正在使用一个子函数来打开、读取和存储列表中的数据,但无法访问其中的字符串,我的意思是,可以看到其他信息,只是看不到那个...
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)] = '[=11=]';
else
linha [strlen(linha) - 1] = '[=11=]';
pv = CriaKW ();
pv->c = linha;
pv->tam = strlen (linha);
P = insertKW (P, pv);
}
fclose (ficheiro);
return (P);
}
结构体"Mensagem"
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);
}
线路有两个问题:pv->c = linha;
- 它在返回的结构中保存了一个指向局部变量的指针。该变量在函数 returns 时被销毁,因此指针不再有效。
- 您对阅读的每一行都使用了相同的
linha
变量。所以即使变量没有被销毁,所有的 Palavra
结构都会有文件的最后一行。
您需要复制该行以保存它。将该行更改为:
pv->c = strdup(linha);
strdup()
是一个 POSIX 函数,不是标准 C。如果这是对您的代码的限制,您使用 malloc()
和 [= 自己编写它应该很简单18=].
顺便说一句,不需要这一行:
linha [strlen(linha)] = '[=11=]';
由于 strlen()
通过找到 [=20=]
字符的位置来工作,这只是将该字符设置为它已有的字符。将包含此内容的 if
更改为:
if (linha[strlen(linha)-1] == '\n') {
linha[strlen(linha)-1] = '[=12=]';
}
数组linha
是函数的局部对象
Palavra* lerPalavras ()
{
char linha [50];
//...
并且有自动保存期限,退出函数后不会存活,可能被程序其他对象覆盖甚至无法访问。
无论如何,每个节点的指针pv->c
都是这样初始化的
pv->c = linha;
退出函数后将有一个无效值。
你应该动态分配此指针指向的内存,并将原始字符串复制到分配的内存中。
例如
linha[ strcspn( linha, "\n" ) ] = '[=12=]';
size_t n = strlen( linha );
pv->c = malloc( n + 1 );
strcpy( pv->c, linha );
pv->tam = n;
还需要记得在删除列表的节点时释放为字符串分配的内存。
考虑到对于数据成员 tam
使用类型 size_t
比类型 long int
更好,因为通常类型 [=] 不是必需的17=] 等同于类型 long int
尽管标准函数 strlen
和其他字符串函数使用类型 size_t.
.
size_t tam;
感谢大家,我是新来的,但你们都尽力提供帮助!非常感谢!
这段代码是否:
pv->c = strdup(linha);
我 "working" 在一个学校项目中需要使用带有 chars* 和其他一些变量的链表。事情是:
我正在使用一个子函数来打开、读取和存储列表中的数据,但无法访问其中的字符串,我的意思是,可以看到其他信息,只是看不到那个...
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)] = '[=11=]';
else
linha [strlen(linha) - 1] = '[=11=]';
pv = CriaKW ();
pv->c = linha;
pv->tam = strlen (linha);
P = insertKW (P, pv);
}
fclose (ficheiro);
return (P);
}
结构体"Mensagem"
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);
}
线路有两个问题:pv->c = linha;
- 它在返回的结构中保存了一个指向局部变量的指针。该变量在函数 returns 时被销毁,因此指针不再有效。
- 您对阅读的每一行都使用了相同的
linha
变量。所以即使变量没有被销毁,所有的Palavra
结构都会有文件的最后一行。
您需要复制该行以保存它。将该行更改为:
pv->c = strdup(linha);
strdup()
是一个 POSIX 函数,不是标准 C。如果这是对您的代码的限制,您使用 malloc()
和 [= 自己编写它应该很简单18=].
顺便说一句,不需要这一行:
linha [strlen(linha)] = '[=11=]';
由于 strlen()
通过找到 [=20=]
字符的位置来工作,这只是将该字符设置为它已有的字符。将包含此内容的 if
更改为:
if (linha[strlen(linha)-1] == '\n') {
linha[strlen(linha)-1] = '[=12=]';
}
数组linha
是函数的局部对象
Palavra* lerPalavras ()
{
char linha [50];
//...
并且有自动保存期限,退出函数后不会存活,可能被程序其他对象覆盖甚至无法访问。
无论如何,每个节点的指针pv->c
都是这样初始化的
pv->c = linha;
退出函数后将有一个无效值。
你应该动态分配此指针指向的内存,并将原始字符串复制到分配的内存中。
例如
linha[ strcspn( linha, "\n" ) ] = '[=12=]';
size_t n = strlen( linha );
pv->c = malloc( n + 1 );
strcpy( pv->c, linha );
pv->tam = n;
还需要记得在删除列表的节点时释放为字符串分配的内存。
考虑到对于数据成员 tam
使用类型 size_t
比类型 long int
更好,因为通常类型 [=] 不是必需的17=] 等同于类型 long int
尽管标准函数 strlen
和其他字符串函数使用类型 size_t.
.
size_t tam;
感谢大家,我是新来的,但你们都尽力提供帮助!非常感谢!
这段代码是否: pv->c = strdup(linha);