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);,它会在按 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() 的调用之一可能返回到错误的地址。

于 2008-10-22T07:07:51.467 回答
0

一种冒险缓冲区溢出的简单方法,因为输出的大小永远不会通过/检查

于 2008-10-22T05:42:11.173 回答
0

这是完整的程序,其中包含您输入的一些更新,但它仍然无法退出循环。顺便说一句,这是第 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 回答
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 回答