Reputation: 15
Recently I went through the section about pointer in the book C Programming Language from K&R. I wrote a C program that converts a word description to valid 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;
}
The problem is that I can only input one line in terminal window. If I try to input the second line and press "Enter" button, the converted result will come out. It seems like Enter works like EOF(Ctrl+Z and Enter) in this program. Why could this happen? Do I miss some important point here? I am new to C so maybe some stupid mistakes have been made. I use Visual Studio 2015 so some library functions like strcpy are replaced with _s alternatives. Thanks for you time and help!
Upvotes: 1
Views: 77
Reputation: 144780
Your code has several problems:
EOF
consistently: you should not let ungetch(EOF)
store character \377
to buf
. Re-reading it from buf may or may not produce -1, depending on whether char
is signed or not by default. Non ASCII characters are not handled correctly because of this. You should make buf
an array of int
.EOF
, check buffer boundaries . You would invoke undefined behavior if EOF is encountered during this phase, or if too many characters are read before the ]
.getch()
and ungetch()
at local scope inside gettoken()
. These forward declarations belong in the global scope.main
should be int main(void)
or int main(int argc, char *argv[])
, not an obsolete incomplete main()
.main
, the inner loop iterates until '\n'
is read. You will not detect EOF
correctly here. Incidentally, it should have the exact opposite effect to what you observe.{}
braces around any non trivial block: the 11 line if
statement that forms the body of the while ((type = gettoken()) != '\n')
in main
is a single statement, but for readability and sturdiness, it is recommended that you put that in a block.I am not sure which issue causes your problem or if it comes from some other source, but you should try and fix these first.
Upvotes: 1