2016-05-09 8 views
0

Я спрашиваю пользователя, какую переменную окружения он хочет узнать, а затем сканирую его с помощью scanf. Но это не работает для меня. Вот мой код:C - scanf(), а затем getenv()

#include <unistd.h> 
    #include <stdio.h> 
    #include <stdlib.h> 


    int main(int argc, char *argv[]){ 

     char *value; 
     char input; 

     printf("Which variable do you want?\n"); 
     scanf("%s", input); 

     value = getenv(input); 

     printf("%s", value); 

    } 

Компилятор говорит:

"Назначение аргумента функции между типами "Const символ *" и "полукокса" ИСТ не допускается"

Так я пытался изменить входную переменную на: char const *input

Теперь нет ошибки компилятора, но когда я отправляю имя, например «USER», я получаю "Segmentation fault (core dumped)" ошибка.

+4

'char input; ... scanf ("% s", input); '->' input' недостаточно велик для хранения ввода текста пользователя. (Аналогичная проблема с http://stackoverflow.com/q/37119782/2410359) – chux

+0

при вызове любого из семейства функций 'scanf()' 1) всегда проверяет возвращаемое значение (а не значение параметра), чтобы обеспечить выполнение операции Был успешен.2) при использовании спецификатора входного преобразования «% s» всегда используйте модификатор «max length» (который меньше, чем длина входного буфера), поэтому пользователь не может перехватить входной буфер (что приведет к неопределенному поведению и может привести к событию сбоя seg). BTW: как вы ожидаете читать в строке (NUL завершенный массив символов), когда входной буфер составляет всего 1 символ? – user3629249

+0

относительно этой строки: 'printf ("% s ", value);' выход будет находиться в буфере stdout до тех пор, пока программа не выйдет, тогда (и только тогда) она будет фактически отображаться на терминале. Строго рекомендуем использовать: 'printf ("% s \ n ", value);' потому что '\ n' (новая строка) приведет к немедленному отображению буфера stdout на терминале. – user3629249

ответ

4

предупреждение потому, что здесь

value = getenv(input); 

вы передаете char к getenv(), который имеет прототип:

char *getenv(const char *name); 

Define input как массив символов, как:

char input[256]; 

    printf("Which variable do you want?\n"); 
    scanf("%255s", input); //specify the width to avoid buffer overflow 

Или вы можете использовать динамическое распределение памяти (используя malloc) если вы считаете, что 256 недостаточно велик для ваших целей.

1

char является одним char.
char *input объявляет переменную, которая содержит указатель на символ, но нет данных для данных. В C это правильное поведение. Однако sscanf ожидает, что вы фактически передадите указатель, который указывает на выделенную память (учтите, что функция не возвращает никакого указателя, поэтому у вас нет шансов выделить вам память).

Таким образом, между декларацией и использованием, используйте malloc для выделения памяти.

2

Когда вы определили char *input;, вы удовлетворяете компилятору, потому что ваш синтаксис действителен: при вызове scanf("%s", input); вы говорите, что хотите строку, и она должна быть помещена туда, где есть input.

Проблема input не где-нибудь (инициализировано) еще ... там, где оно указывает, в данный момент не определено; прежде чем использовать какой-либо указатель, вы должны указать, что он находится где-то, что является действительным (и достаточно большим, чтобы удерживать все, что вы намереваетесь положить туда).

Есть несколько способов решить эту проблему, но, пожалуй, самым простым является решение о том, насколько большой должен быть вход и объявить массив символов, например: char input[512];. Имейте в виду, что это проблематично, потому что, если вход превышает ваш буфер, вы перезапишете другую память ... но это должно заставить вас двигаться вперед.