0

I have the following code:

#include <stdio.h>

char * lookLine (FILE *fichero) 
{
    char p[25];
    fgets (p, sizeof (p), fichero);
    return p;
}

int main (void) {
    printf ("%s\n", lookLine (fopen ("suma.c", "r")));
    return 0;
}

And I get the following output:

#��x�

Not nice. My intention is to print out the first line of the file whose name "suma.c". It should print out the following:

#include <stdio.h>

Nevertheless, if I print out the content of p string into the same lookFile function, it does it fine:

#include <stdio.h>

void lookLine (FILE * fichero) 
{
    char p[25];
    fgets (p, sizeof (p), fichero);
    printf ("%s\n", p);
}

int main (void) {
    lookLine (fopen ("suma.c", "r"));
    return 0;
}

And the output I get now is the correct one:

#include <stdio.h>

My reasoning is this: by using fgets I save the string of the first line of "name.c" in the p array and I return its address, which is taken by the second argument of printf function in main.
But I have found out that this only works when I use the printf function directly into the same lookLine function...

Please, could someone tell me what's really going on here?

4

3 回答 3

6

read这是因为您正在从函数返回一个指向本地数组的指针。

请记住,局部变量存储在堆栈中,其中包括数组。当函数返回时,编译器会回收堆栈空间以供其他函数调用使用。所以你有一个指向另一个函数内存的指针。

于 2013-05-25T15:52:21.130 回答
2

数组的生命周期在语句p处结束(技术上是一个具有自动存储持续时间的局部变量;这意味着它的生命周期在匹配时结束)。returnp}

然后程序调用未定义的行为,因为它使用了一个不确定的值(从不再指向有效内存的指针读取)。这就是您可以在 中打印字符串read(),但从main().

请注意,这read是一个 POSIX 函数,可能会干扰您定义的函数(在严格的 C89 或 C99 模式下不是问题,但大多数编译器默认情况下不是问题)。[同时,OP 将函数重命名为lookLine().]

于 2013-05-25T16:00:43.317 回答
1

正如 Joachin Pileborg 正确指出的那样,当您从函数返回时,您正试图返回一个将被回收的堆栈变量。

相反,您可以尝试将字符数组及其大小作为函数的输入传递给 read。顺便说一句,如果您除了在 r​​ead 函数中调用 fgets 之外不打算做任何其他事情,那么最好在 main 函数本身中调用 fgets 。

如果您在读取中执行一些额外的逻辑,并且您也无法将缓冲区及其大小作为读取函数的输入传递,您可以使用 malloc 分配读取所需的内存并将指针返回给调用函数。但是,就个人而言,我不会推荐它,因为最好确保读取的调用者负责创建和删除数组。

于 2013-05-25T16:02:01.100 回答