사용자 정의 얻기 라인 입력 기능
-
03-07-2019 - |
문제
나는 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);
, 그것은 Enter를 치고 새 라인을 작성한 후 모든 입력을 잘 인쇄합니다.
해결책
다음에 무슨 문제가 있습니까?
1. void getInput(int* output) {
캐릭터 배열에 저장하려는 것이 입력 인수가 int* 인 이유는 무엇입니까? 아마
void getInput(char* output) {
더 나은.
또한 출력 포인터가 사용자의 입력을 작성하기에 충분한 메모리를 보유한 곳을 가리키고 있음을 어떻게 알 수 있습니까? 어쩌면 버퍼 오버 플로우 오류를 피하기 위해 추가 매개 변수로 최대 버퍼 길이가 있어야합니다. PW가 지적했다.
5. output[++i] = '\0';
For Loop 내부에서 이미 추가 시간이 증가 했으므로 다음과 같이 할 수 있습니다.
output[i] = '\0';
이 외에, 프로그램은 정상으로 실행되며 반환 될 때까지 입력 한 내용을 출력합니다.
fwiw, 나는 그렇게 부르면서 그것을 테스트했습니다.
int main(void)
{
char o[100];
getInput(o);
printf("%s", o);
return 0;
}
다른 팁
루프 외부에서 I를 증가시킬 필요가 없다는 점을 제외하고는 작성대로 나에게 정확해 보입니다. I는 루프 종료 직전에 증가하여 이미 원하는 곳입니다.
A ' n'이 실제로 C로 만들고 있는지 확인하십시오.
때때로 ' n'은 구분 기호로 버려집니다.
게시 된 마지막 코드에는 3 가지 오류가 있습니다.
char* userInput[MAX_INPUT_SIZE];
해야한다:
char userInput[MAX_INPUT_SIZE+1];
(이것은 이미 Pax Diablo에 의해 언급되었습니다)
getInput(&userInput);
해야한다:
getInput( userInput );
이 마지막 오류는 통화 스택 내부의 주소를 얻기 위해 통과했음을 의미합니다. 메모리 덮어 쓰기가 있습니다. getChar ()에 대한 전화 중 하나가 잘못된 주소로 돌아갑니다.
출력의 크기가 전달/확인되지 않기 때문에 버퍼 오버플로 위험을 위험에 빠뜨리는 간단한 방법
디버거를 사용해 보셨습니까? GDB 또는 Visual Studio 또는 사용중인 Code의 코드를 통해 진행중인 작업을 확인해야합니다. 당신은 당신이 초보자라고 말 했으므로 아마도 당신은 아직 그것을 고려하지 않았을 것입니다 - 이것은 사용하기에 꽤 정상적인 디버깅 기술입니다.
다음은 입력의 몇 가지 업데이트가 포함 된 완전한 프로그램이지만 여전히 루프에서 벗어나지는 않습니다. BTW 이것은 pg 34에서 운동 1-24였습니다
#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);
}