在C语言中返回字符指针

5

我正在开发一款用C语言编写的文件共享程序。有一个函数可以读取数据文件并将数据存储到字符串中,将该字符串返回给主函数,然后主函数会再将其发送回客户端。代码如下:

char* ListFiles(){
    FILE *fp;
    char file[30];
    char *f;
    if((fp=fopen("list","r"))==NULL)  
    {
        ...
    }
    while (!feof(fp))
    {
        fgets(file,50,fp);
    }
    fclose(fp);
    f=file;
    printf("%s",f); //get display!!!
    return f;
}
int main(){
      char *files;
      ...
      ...
      files=ListFiles();
      printf("%s",files); //nothing display!!
      sent();
}

然而,这种方式并不起作用。没有任何显示,当然也没有发送任何内容。但是在函数ListFiles()中我确实得到了正确的显示。我不知道发生了什么事情。我还使用了strcpy(),但仍然无法工作。

1
char file[30]; char *f; f = file; 这里发生的事情并不好。请花一秒钟思考并正确书写它。 - Griwes
2
这与此无关,但是您的“file”变量只能容纳30个字符,而您正在读取超过该长度的内容。file将会溢出。 - rid
1
此外,fgets将会重复使用相同的缓冲区直到文件结束,因此在循环之后,缓冲区将只包含文件的最后一部分。 - Mr Lister
这里有一个很好的例子,展示了如何在C语言中使用字符串和指针来完成不同的任务。https://stackoverflow.com/a/46344713/5842403 - Joniale
6个回答

10

按照George Skoptsov的建议进行操作。但是,如果你没有strdup()函数,那么请使用以下内容:

char* strdup(const char* org)
{
    if(org == NULL) return NULL;

    char* newstr = malloc(strlen(org)+1);
    char* p;

    if(newstr == NULL) return NULL;

    p = newstr;

    while(*org) *p++ = *org++; /* copy the string. */
    return newstr;
}

然后:

#include <string.h> /* strlen() call */
#include <stdlib.h> /* NULL, malloc() and free() call */

/* do something... */

char* ListFiles() {
        /* .... */ 
         return strdup(f);
}

或者,可以使用动态内存分配,取代char file[30];char* file = malloc(30); 然后你就可以执行return f;,程序可以正常工作,因为此时f不再是指向本地变量的指针。


即使没有 strdup 函数,只要包含了 <string.h> 头文件,你总是有 strcpy 函数可用。 - Mr Lister
1
这里有一个很好的例子,展示了如何在C语言中使用字符串和指针来完成不同的任务。https://stackoverflow.com/a/46344713/5842403 - Joniale

9
你所做的是返回一个指向本地变量的指针,该变量曾经在堆栈上分配。
将你的返回语句改为:
return strdup(file);

5
strdup 不是标准函数,它仅在 MSVC 中定义。 - Mr Lister
3
@MrLister:它也可以在POSIX环境下使用。 - Jack

4

fileListFiles() 中的一个栈变量,你正在返回它的指针。一旦从该函数返回,变量将停止存在,因此返回的指针将无效。

如果你想返回一个字符串,你应该在堆上分配它,返回它,使用它,然后在使用完毕后释放它。


2

您正在返回指向堆栈变量的指针。当函数返回时,堆栈被弹出。堆栈变量不再存在,指针变成了悬空指针。

一个解决方案是在主函数中分配适当数量的内存,并将指向内存的指针传递给辅助函数。


0

不应该返回存储在自动存储器上的数据,当你返回时,它就超出了作用域。


作用域和存储期是两个不同的概念。 - ouah

0
你正在尝试显示一个分配在栈(函数栈)上的字符串值char file[30]。该内存的内容在方法返回后不能保证。你应该动态分配它(例如malloc),或者最终使用全局值,或者将其分配到外部函数的堆栈上(例如你的示例main()函数)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接