我正在读《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循环内增加了额外的时间,所以你可以这样做:

output[i] = '\0';

除此之外,程序运行正常并输出我们输入的内容直到返回。

FWIW,我通过调用它来测试它:

 int main(void)
{
    char o[100];
    getInput(o);
    printf("%s", o);
    return 0;
}

其他提示

它对我来说看起来是正确的,除了你不需要在循环之外增加 i 之外。i 在循环退出之前递增,因此它已经是您想要的位置。

确保 ' ' 实际上将其放入 c 中。

有时,“ ”作为分隔符会被丢弃。

您发布的最后一个代码有3个错误我可以看到:

char* userInput[MAX_INPUT_SIZE];

应该是:

char userInput[MAX_INPUT_SIZE+1];

(Pax Diablo已经提到过)

getInput(&userInput);

应该是:

getInput( userInput );

这最后一个错误意味着您将getInput传递给调用堆栈中的地址。你有记忆覆盖。可能你对getchar()的一个调用返回错误的地址。

冒险缓冲区溢出的简单方法,因为输出的大小永远不会被传递/检查

您是否尝试过使用调试器?你应该逐步浏览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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top