2013-11-07 4 views
1

Это мой первый вопрос, поэтому я извиняюсь, если это не полезный вопрос.Почему мой код ведет себя так?

У меня есть проект симулятора, где пользователь вызывает программу через командную строку с некоторыми параметрами. Нравится, MYPROG [options] filename.

Мне нужно убедиться, что имя файла действительно, где оно (каталог) и получить имя для дальнейшего использования.

Вот часть кода:

char* ExtrairNome(char* alvo){ 
    char* teste = alvo; 
    char* nome = NULL; 
    int barras = 0; 

    while(strcmp(teste, "") != 0){ //look for "/" 
     if (teste[0] == '/') barras++; 
     teste++; 
    } 

    teste = alvo; 
    if (barras > 0){ 
     while(barras > 0){ //remove everything leaving the "filename.ias" 
      if (teste[0] == '/') barras--; 
      teste++; 
     } 
    } 

    int i = 0; 
    char aux[strlen(teste) - 4]; 
    while (strcmp(teste, ".ias")){ //remove the ".ias" 
     aux[i] = teste[0]; 
     teste++; 
     i++; 
    } 
    printf("random %d\n", barras); //this line fixes the bug!! 
    aux[i] = '\0'; 
    nome = aux; 
    return nome; 
} 

Эта функция принимает строку с полным именем файла и должен возвращать только имя, без пути или расширением. Но он работает только тогда, когда я печатаю некоторую переменную перед возвратом. Если я удалю эту строку, функция ничего не вернет. Я думаю, что это имеет какое-то отношение к сфере видимости, но я точно не знаю. Как я могу это исправить?

+0

Вы фактически возвращает локальную переменную по указателю. Это приведет к неопределенному поведению. Заставьте функцию принимать выделенный вызывающим вызовом буфер и записать вместо этого. – LumpN

+0

Для проверки пустой строки просто 'while (teste [0])' достаточно, не нужно вызывать 'strcmp (teste," ")! = 0', который намного медленнее –

ответ

1

nome - это указатель, поэтому вы можете вернуть адрес решения. Проблема - это aux, находящийся в стеке, и как только вы вернетесь, он больше не существует, поэтому поведение неизвестно. У вас есть два варианта, объявляя «aux» в более высокой области и передавая его вашей функции, и передавая указатель на буферное решение или выделяя в функции (используя malloc), а затем бесплатно (когда это не нужно).

я имею в виду:

char name[100]; 
ExtrairNome(alvo, name);//pass a pointer to the function 

void ExtrairNome(char * alvo, char * aux) 
{ 
    ...;//everything is the same 
    //except you don't create aux here, you use the one you created in your main function 
} 

или

char * ExtrairNome(char * alvo, char * aux) 
{ 
    ...;//everything is the same 
    char * aux = (char*)malloc((strlen(teste)-4)* sizeof(char)); 
    ...;//everything the same 
} 
//remember to free() when you are done using it 
+0

Другим решением было бы объявить aux как' static ', то он все равно будет существовать вне функции. (Обычно я считаю, что это плохой дизайн программы, но это вариант.) – karadoc

+0

Правда, вы также можете объявить его глобальной, но все же не очень хорошей практикой, у статики есть еще одна причина быть там. – Sinn

+0

Я попытаюсь использовать 'malloc' и изменить тип возврата на void. @karadoc Я не могу использовать static, поскольку размер является переменной. –

0

Вы возвращаете указатель на локальную автоматическую (стек) переменную - aux. Это не существует после возвращения функции. Это неопределенное поведение. Тот факт, что он «работает» при печати переменной, является одной возможностью для неопределенного поведения.

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