2008-10-22 7 views
2

Я читаю книгу K & R, и я немного застрял.Пользовательская функция ввода линии ввода

Что не так в следующем?

void getInput(int* output) { 
    int c, i; 
    for(i=0; (c = getchar()) != '\n'; i++) 
    output[i] = c; // printf("%c", c) prints the c value as expected 
    output[++i] = '\0'; 
} 

При запуске программы она никогда не выходит из цикла, и я должен Ctrl + C для выхода. Однако, если я заменю пятую строку на printf("%c", c);, она полностью выведет все входные данные после нажатия ввода и создания новой строки.

+0

Кажется работать для меня. – pc1oad1etter 2008-10-22 05:40:19

+0

Вы нажимаете клавишу ввода? И, покажите нам весь код, вы не можете правильно обращаться к getInput. И, выход должен быть символом char *. – paxdiablo 2008-10-22 05:49:37

+0

++ в output [++ i] означает, что вы пропускаете одну запись в своем массиве - обычно это массив символов, а не массив int, как указал Pax Diablo. Другие люди отметили, что вы не проверяете EOF и что вы не проверяете переполнение буфера. Теперь вы должны начать изучать хорошие привычки. – 2008-10-22 05:58:38

ответ

7

Что случилось со следующими?

1. void getInput(int* output) { 

Почему входной аргумент является ИНТ * когда то, что вы хотите хранить в массив символов? Возможно

void getInput(char* output) { 

лучше.

Кроме того, откуда вы знаете, что указатель вывода указывает где-то, где у вас достаточно памяти для записи ввода пользователя? Возможно, вы должны иметь максимальную длину буфера в качестве дополнительного параметра, чтобы избежать ошибок переполнения буфера, как PW pointed out.

5. output[++i] = '\0'; 

я уже увеличивается дополнительное время внутри для цикла, так что вы можете просто сделать:

output[i] = '\0'; 

Кроме этого, программа прекрасно работает и не выдает то, что мы ввода до возвращения.

FWIW, я проверил его, называя его так:

int main(void) 
{ 
    char o[100]; 
    getInput(o); 
    printf("%s", o); 
    return 0; 
} 
1

Это выглядит правильно для меня, как написано, за исключением того, что вам не нужно увеличивать i за пределами цикла. Я получаю инкремент прямо перед выходом из цикла, поэтому он уже там, где вы этого хотите.

Убедитесь, что '\ n' фактически превращает его в c.

Иногда «\ n» будет выбрасываться в качестве разделителя.

0

простой способ риск переполнения буфера, поскольку размер выходного никогда не передается/проверено

+0

У меня было это раньше, но у меня проблема с кодом, который он разделил, чтобы было легче найти проблему. – chris 2008-10-22 05:52:00

0

Вот полная программа с парой обновлений от вашего входа, но он по-прежнему не будет делать его из петли. Кстати это было упражнение 1-24 на стр. 34

#include <stdio.h> 

#define STACK_SIZE 50 
#define MAX_INPUT_SIZE 1000 
#define FALSE 0 
#define TRUE 1 

void getInput(); 
int validInput(); 

int main() { 
    char* userInput[MAX_INPUT_SIZE]; 

    getInput(&userInput); 

    if (validInput(&userInput) == TRUE) 
    printf("Compile complete"); 
    else 
    printf("Error"); 
} 

// Functions 
void getInput(char* output) { 
    int c, i; 
    for(i=0; (c = getchar()) != '\n' && c != EOF && i <= MAX_INPUT_SIZE; i++) 
    output[i] = c; 
    output[i] = '\0'; 
} 

int validInput(char* input) { 
    char stack[STACK_SIZE]; 
    int c; 
    int j; 

    for (j=0; (c = input[j]) != '\0';) { 
    switch(c){ 
     case '[': case '(': case '{': 
     stack[j++] = c; 
     break; 
     case ']': case ')': case '}': 
     if (c == ']' && stack[j] != '[') 
      return FALSE; 
     else if (c == '}' && stack[j] != '{') 
      return FALSE; 
     else if (c == ')' && stack[j] != '(') 
      return FALSE; 

     // decrement the stack's index 
     --j; 
     break; 
    } 
    } 

    return TRUE; 
} 
0

Вы пробовали использовать отладчик? Вы должны пройти через код в gdb или visual studio или что бы вы ни использовали, и посмотреть, что происходит. Вы сказали, что вы новичок, поэтому, возможно, вы еще не подумали об этом - это довольно обычная технология отладки.

1

ваш последний код, как писал есть 3 ошибки я вижу:

char* userInput[MAX_INPUT_SIZE]; 

Должно быть:

char userInput[MAX_INPUT_SIZE+1]; 

(это уже упоминалось Пакс Diablo)

getInput(&userInput); 

В случае, если be:

getInput(userInput); 

Эта последняя ошибка означает, что вы передали getInput адрес внутри стека вызовов. вы перезаписываете память. вероятно, один из ваших вызовов getchar() возвращается к неправильному адресу.

0

Вот окончательный рабочий код. Должен сказать, я немного подхватил это. Спасибо за помощь и указатели.

Любые предложения о том, как можно улучшить ситуацию?

#include <stdio.h> 

#define STACK_SIZE 50 
#define MAX_INPUT_SIZE 1000 
#define FALSE 0 
#define TRUE !FALSE 

void get_input(); 
int valid_input(); 

int main() { 
    char user_input[MAX_INPUT_SIZE + 1]; // +1 for the \0 

    get_input(user_input); 

    if (valid_input(user_input)) 
    printf("Success\n"); 
    else 
    printf("Error\n"); 
} 

// Functions 
void get_input(char* output) { 
    int c, i; 
    for(i=0; (c = getchar()) != '\n' && c != EOF && i <= MAX_INPUT_SIZE; i++) 
    output[i] = c; 
    output[i] = '\0'; 
} 

int valid_input(char* input) { 
    char stack[STACK_SIZE]; 
    char c; 
    int i = 0; 
    int stack_index = -1; 

    while ((c = input[i]) != '\0' && i < STACK_SIZE) { 
    switch(c){ 
     case '[': case '(': case '{': 
     stack_index++; 
     stack[stack_index] = c; 
     break; 
     case ']': case ')': case '}': 
     if ((c == ']' && stack[stack_index] != '[') || 
      (c == '}' && stack[stack_index] != '{') || 
      (c == ')' && stack[stack_index] != '(')) 
      return FALSE; 

     // decrement the stack's index now that the closing bracket is found 
     stack_index--; 
     break; 
    } 
    i++; 
    } 

    // stack index should be back where it started 
    return (stack_index == -1); 
} 
Смежные вопросы