カスタム入力行入力関数
-
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 で終了する必要があります。ただし、5行目を printf("%c&quot ;, c);
に置き換えると、Enterキーを押して新しい行を作成した後、すべての入力が正常に出力されます。
解決
次の何が問題になっていますか
1. void getInput(int* output) {
文字の配列に何を格納したいのに、入力引数がint *なのですか? おそらく
void getInput(char* output) {
の方が優れています。
また、出力ポインターがユーザーの入力を書き込むのに十分なメモリを保持している場所を指していることをどのようにして知るのですか? PWが指摘したように、バッファオーバーフローエラーを回避するための追加パラメータとして最大バッファ長が必要な場合があります。
5. output[++i] = '\0';
iは既に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];
(これはすでにPax Diabloによって言及されました)
getInput(&userInput);
はずです:
getInput( userInput );
この最後のエラーは、呼び出しスタック内のアドレスをgetInputに渡したことを意味します。メモリが上書きされています。おそらくgetchar()の呼び出しの1つが間違ったアドレスに戻ります。
出力のサイズが渡されたりチェックされたりすることはないため、バッファオーバーフローのリスクを冒す簡単な方法
デバッガを使用してみましたか? gdbやvisual studioなどのコードをステップスルーして、何が起こっているのかを確認する必要があります。あなたは初心者だと言っていたので、まだ考えていなかったのかもしれません-これはかなり普通のデバッグ手法です。
これは、入力からの更新をいくつか含む完全なプログラムですが、それでもループから抜け出すことはできません。ところで、これはページ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);
}