2015-04-08 3 views
2

У меня есть цикл while, который вводит пользовательский ввод до тех пор, пока пользователь не говорит о выходе, но я не уверен, как правильно объявлять строки. Если пользователь вводит только одно слово, вторая переменная останется прежним значением из предыдущего цикла.Как вы объявляете временные строки для повторного использования в C?

int main(int argc, char * argv[]){ 
    char user_input[25]; 
    char var1[25], var2[25]; 
    while(strcmp(var1, "quit") != 0){ 
     clear_buffer(user_input); 
     fgets(user_input, 30, stdin); 
     sscanf(user_input, "%s %s", var1, var2); 
     do_stuff(var1, var2); 
    } 
    printf("%s", "Done\n"); 
+3

'fgets (user_input, 30' кажется неправильным, учитывая буфер только 25 байт. –

+0

' var1' не инициализирован при первом входе в цикл. – chqrlie

+0

@DigitalNinja : Я думаю, что некоторые команды имеют только одно слово, и в этом случае второе слово должно быть передано как строка с нулевой длиной. –

ответ

1

Несколько проблем

  1. Вы никогда не инициализировать var1 но вы используете strcmp(), вы должны инициализировать var1, прежде чем пытаться использовать strcmp(), если вы хотите инициализировать в пустую строку просто

    var1[0] = '\0'; 
    
  2. Вы передаете 30 в fgets(), но user_input может содержать только 25 символов.

Теперь почему программа ведет себя так, как это, вы должны проверить, что sscanf() прочитал обе строки, если это не так, не изменяет переданные параметры.

scanf() функция возвращает количество спецификаторов подобранных по входу, так что если

  1. scanf() возвращает 0, это означает, что оба параметра не инициализируются/изменены.
  2. scanf() возвращает 1 один из параметров инициализирован/изменен.
  3. Если оба были инициализированы/изменены, то он вернет 2, поэтому проверка этого позволит вам узнать, что происходит не так, и вы можете распечатать строку ввода, чтобы убедиться, что scanf() был прав, и вход был неправильным ..
+0

Хех, исправление вашего последнего сообщения: если 'scanf' не читает обе строки, ему нужно очистить параметр (ы). –

1
char user_input[50+1]; 
char var1[25], var2[25]; 

while(fgets(user_input, sizeof(user_input), stdin)){ 
    int state = sscanf(user_input, "%24s %24s", var1, var2); 
    if(state == 1 && strcmp(var1, "quit") == 0) 
     break; 
    else if(state == 2) 
     do_stuff(var1, var2); 
} 
+0

Почему «quit now» вызывается 'do_stuff' и что еще более важно, почему команды без аргументов игнорируются? – chqrlie

+0

Если есть два входа на вход I, считается, что вы не хотите включать выход. Это потому, что, когда вы хотите остановить его, нет необходимости указывать второй аргумент. также Если два входа не являются, то я считаюсь недействительным. Причина в том, что 'do_stuff' требует два аргумента. – BLUEPIXY

+0

Требования, по меньшей мере, не определены из вопроса ОП. Ваш аргумент о 'quit' является спорным. Как насчет команд без аргумента? Просто игнорирование их кажется неправильным. – chqrlie

1

Вот модифицированная версия с замечания во внимание и защиту sscanf аргументы:

int main(int argc, char *argv[]) { 
    char user_input[80]; 
    char var1[25], var2[25]; 

    while (fgets(user_input, (int)(sizeof user_input), stdin)) { 
     *var2 = '\0'; 
     if (sscanf(user_input, "%24s %24s", var1, var2) > 0) { 
      if (!strcmp(var1, "quit")) 
       break; 
      do_stuff(var1, var2); 
     } 
    } 
    printf("Done\n"); 
    return 0; 
} 
4

я не знаю, как правильно объявить строки

Строки не являются типом. Они представляют собой шаблон значений, и, как и другие ценности, мы не объявляем их; мы назначаем их (используя в этом случае strcpy и другие функции). Если вы скажете, что int хранит несколько десятков, то он заканчивается на 0 ... Если вы говорите, что массив char хранит строку, то он заканчивается на первом '\0'. Вы видите рисунок еще? Мы можем хранить десятикратные числа в разных типах целочисленных переменных, а также для строк мы можем выбирать различные типы массивов символов. Аналогично для хранения числовых значений в переменных integer при объявлении массива для хранения строки вы должны быть уверены, что в массиве достаточно места для хранения всех символов для строки плюс '\0' в конце.

Если пользователь вводит только одно слово, вторая переменная останется прежним значением из предыдущего цикла.

Проверьте возвращаемое значение sscanf.

Например, при рассмотрении вопроса int x = sscanf(user_input, "%s %s", var1, var2); вы можете быть уверены, что 2 аргументам, указанным вами sscanf, присвоены, и в этом случае вы будете проверять это x == 2. Если вам всего лишь нужен первый назначенный аргумент, то вы будете счастливы, когда x == 1 тоже. Однако, если x <= 0 то вы не можете доверять ни var1 или var2

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