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終了する必要があります。ただし、5 行目を に置き換えるとprintf("%c", c);、Enter キーを押して新しい行を作成した後、すべての入力が正常に出力されます。

4

7 に答える 7

7

次の何が間違っていますか?

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;
}
于 2008-10-22T05:58:07.273 に答える
1

ループの外側で i をインクリメントする必要がないことを除いて、書かれているように私には正しいように見えます。i はループが終了する直前にインクリメントされるため、すでに必要な場所にあります。

'\n' が実際に c になっていることを確認してください。

'\n' が区切り文字として捨てられることがあります。

于 2008-10-22T05:39:14.407 に答える
1

投稿された最後のコードには、私が見ることができる3つのエラーがあります:

char* userInput[MAX_INPUT_SIZE];

次のようにする必要があります。

char userInput[MAX_INPUT_SIZE+1];

(これはすでに Pax Diablo によって言及されていました)

getInput(&userInput);

次のようにする必要があります。

getInput( userInput );

この最後のエラーは、コール スタック内のアドレスを getInput に渡したことを意味します。メモリの上書きがあります。おそらく、getchar() への呼び出しの 1 つが間違ったアドレスに返されます。

于 2008-10-22T07:07:51.467 に答える
0

出力のサイズが渡されたりチェックされたりしないため、バッファオーバーフローのリスクを冒す簡単な方法

于 2008-10-22T05:42:11.173 に答える
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);
}
于 2008-10-23T04:09:37.007 に答える
0

これは、入力からいくつかの更新を加えた完全なプログラムですが、それでもループから抜け出すことはできません。ところで、これは 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;
}
于 2008-10-22T06:00:17.173 に答える
0

デバッガを使ってみましたか? gdb や Visual Studio など、使用しているコードをステップ実行して、何が起こっているかを確認する必要があります。あなたは初心者だと言ったので、まだ考えていなかったかもしれません - これはかなり普通のデバッグテクニックです。

于 2008-10-22T06:52:37.193 に答える