Пользовательская функция ввода строки
-
03-07-2019 - |
Вопрос
Я читаю книгу K & amp; 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);
, он будет печатать все входные данные очень хорошо после нажатия клавиши ввода и создания новой строки.
Решение
Что не так со следующим?
1. void getInput(int* output) {
Почему входной аргумент является int *, если вы хотите сохранить массив символов? Вероятно,
void getInput(char* output) {
лучше Р>
Кроме того, откуда вы знаете, что указатель вывода указывает на то место, где у вас достаточно памяти для записи ввода пользователя? Возможно, вы должны указать максимальную длину буфера в качестве дополнительного параметра, чтобы избежать ошибок переполнения буфера, как указано PW . р>
5. output[++i] = '\0';
я уже был увеличен на дополнительное время внутри цикла for, так что вы можете просто сделать:
output[i] = '\0';
Кроме этого, программа работает нормально и выводит то, что мы вводим, до возврата.
FWIW, я проверил это, назвав это так:
int main(void)
{
char o[100];
getInput(o);
printf("%s", o);
return 0;
}
Другие советы
Для меня это выглядит правильно, как написано, за исключением того, что вам не нужно увеличивать i вне цикла. Значение i увеличивается прямо перед выходом из цикла, поэтому оно уже там, где вы хотите.
Убедитесь, что '\ n' действительно превращается в c.
Иногда '\ n' отбрасывается как разделитель.
Ваш последний опубликованный код содержит 3 ошибки, которые я вижу:
char* userInput[MAX_INPUT_SIZE];
Должно быть:
char userInput[MAX_INPUT_SIZE+1];
(это уже упоминалось Пакс Диабло)
getInput(&userInput);
Должно быть:
getInput( userInput );
Эта последняя ошибка означает, что вы передали getInput адрес внутри стека вызовов. у вас есть перезапись памяти. возможно, один из ваших вызовов getchar () возвращается не по адресу.
простой способ рискнуть переполнением буфера, потому что размер вывода никогда не передается / проверяется
Вы пробовали использовать отладчик? Вы должны пройтись по коду в GDB или Visual Studio или что вы используете, и посмотреть, что происходит. Вы сказали, что были новичком, так что, возможно, вы еще не учли это - это довольно обычная техника отладки.
Вот полная программа с парой обновлений от вашего ввода, но она все равно не выйдет из цикла. Кстати, это было упражнение 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;
}
Вот окончательный рабочий код. Я должен сказать, что немного поднял от этого. Спасибо за помощь и указатели.
Есть предложения о том, как можно сделать лучше?
#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);
}