2012-04-12 3 views
4

Я работаю над какой-то программой обмена файлами, которая написана на C. Существует функция, которая может читать файл данных и хранить данные в строке и возвращать эту строку в главную функцию и основная функция отправляется обратно клиенту. Коды показаны нижеВозвращение указателя char в 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' будет вызываться повторно с тем же буфером, пока файл не достигнет конца, так что после цикла буфер будет содержать только последнюю часть файла. –

ответ

7

Выполнение 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]; сделать dynamic memory allocation: char* file = malloc(30);, то вы можете сделать return f;, и он будет отлично работает потому что f теперь не является указателем на локальную переменную.

+0

Даже если у вас нет 'strdup', у вас всегда есть' strcpy' при включении '' ... –

+0

Вот хороший пример того, как делать разные вещи со строками и указателями в C https: // stackoverflow. ком/а/46344713/5842403 – Joniale

8

Что вы делаете, это возврат указателя на локальную переменную, которая ранее была выделена в стеке.

Изменить оператор возврата к

return strdup(file); 
+5

'strdup' не является стандартной функцией, он определен только в MSVC. –

+1

@MrLister: он доступен и в среде POSIX. – Jack

4

file переменная стека в ListFiles() и вы возвращает указатель на него. Как только вы вернетесь из этой функции, переменная перестанет существовать, поэтому возвращаемый указатель будет недействительным.

Если вы хотите вернуть строку, вы должны allocate it on the heap, верните ее, используйте, а затем освободите ее, как только вы закончите использовать ее.

0

Вы не должны возвращать данные, которые находятся на автоматическом хранилище, когда вы возвращаете его, выходит за рамки.

+0

Объем и продолжительность хранения - это два разных зверя. – ouah

0

Вы пытаетесь отобразить файл символа строкового значения [30], выделенный в стеке (стек функций). Содержимое этой памяти не гарантируется после возврата метода. Вы должны выделить его динамически (для примера malloc) или в конечном итоге использовать глобальное значение или выделить его в стек внешней функции (в вашей функции main())

0

Вы возвращаете указатель на переменную стека , Когда функция возвращается, стек вылетает. Переменная стека больше не существует, указатель становится висящим указателем.

Одним из решений является выделение соответствующего объема памяти в основной функции и передача указателя в память вспомогательной функции.

Смежные вопросы