gpt4 book ai didi

C: 在终端窗口中按 "Enter"就像 EOF

转载 作者:太空宇宙 更新时间:2023-11-04 03:31:43 24 4
gpt4 key购买 nike

最近我浏览了 K&R 的 C Programming Language 一书中关于指针的部分。我写了一个 C 程序,将单词描述转换为有效的 C:

//This program converts a word description like "x is a function returning
//a pointer to an array of pointers to functions returning char," which we will express as
// x () * [] * () char
// to
// char (*(*x())[])()

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXTOKEN 100
#define BUFSIZE 100

enum { NAME, PARENS, BRACKETS};

char buf[BUFSIZE];
int bufp = 0;
int gettoken(void);
int tokentype;
char token[MAXTOKEN];
char out[1000];

main() {
int type;
char temp[MAXTOKEN];

while (gettoken() != EOF) {
strcpy_s(out, 1000, token);
while ((type = gettoken()) != '\n')
if (type == PARENS || type == BRACKETS)
strcat_s(out, 1000, token);
else
if (type == '*') {
sprintf_s(temp, MAXTOKEN, "(*%s)", out);
strcpy_s(out, 1000, temp);
} else
if (type == NAME) {
sprintf_s(temp, MAXTOKEN, "%s %s", token, out);
strcpy_s(out, 1000, temp);
} else
printf("invalid input at %s\n", token);
printf("%s\n", out);
}
return 0;
}

int gettoken(void) {
int c, getch(void);
void ungetch(int);
char *p = token;

while ((c = getch()) == ' ' || c == '\t')
;
if (c == '(') {
if ((c = getch()) == ')') {
strcpy_s(token, MAXTOKEN, "()");
return tokentype = PARENS;
} else {
ungetch(c);
return tokentype = '(';
}
} else
if (c == '[') {
for (*p++ = c; (*p++ = getch()) != ']'; )
;
*p = '\0';
return tokentype = BRACKETS;
} else
if (isalpha(c)) {
for (*p++ = c; isalnum(c = getch());)
*p++ = c;
*p = '\0';
ungetch(c);
return tokentype = NAME;
} else
return tokentype = c;
}

int getch(void) {
return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) {
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}

问题是我只能在终端窗口输入一行。如果我尝试输入第二行并按“Enter”按钮,转换后的结果就会出来。在此程序中,Enter 的工作方式类似于 EOF(Ctrl+Z 和 Enter)。为什么会这样?我在这里错过了一些重要的点吗?我是 C 的新手,所以可能犯了一些愚蠢的错误。我使用 Visual Studio 2015,因此一些库函数(如 strcpy)被替换为 _s 替代项。感谢您的宝贵时间和帮助!

最佳答案

您的代码有几个问题:

  • 您没有一致地处理 EOF:您不应该让 ungetch(EOF) 将字符 \377 存储到 buf。从 buf 重新读取它可能会或可能不会产生 -1,这取决于默认情况下 char 是否已签名。因此,无法正确处理非 ASCII 字符。您应该使 buf 成为一个 int 数组。
  • 为什么解析括号中的字符,不测试 EOF,检查缓冲区边界。如果在此阶段遇到 EOF,或者如果在 ] 之前读取了太多字符,您将调用未定义的行为。
  • 您不应在 gettoken() 内的局部范围内声明 getch()ungetch()。这些前向声明属于全局范围。
  • main 的原型(prototype)应该是int main(void)int main(int argc, char *argv[]),而不是一个过时的不完整 main()
  • main 中,内部循环迭代直到读取 '\n'。您将无法在此处正确检测到 EOF。顺便说一下,它的效果应该与您观察到的完全相反。
  • 请注意,您应该在任何重要 block 周围使用 {} 大括号:第 11 行 if 语句构成 while ((type = main 中的 gettoken()) != '\n') 是单个语句,但为了可读性和稳定性,建议您将其放在一个 block 中。

我不确定是哪个问题导致了您的问题,或者它是否来自其他来源,但您应该先尝试解决这些问题。

关于C: 在终端窗口中按 "Enter"就像 EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35976265/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com