我一直在尝试从输入中获取变量。所以我得到每个单词,并检查它是否是保留数组的一部分。如果它是保留数组的一部分,我从输入中获取下一个单词,这是一个变量。
下面是保留数组:
char *reserved[] = {
"char", NULL
};
该程序有两个输入。一个有type.h
,另一个有ctype.h
。第一个输入有效,但第二个输入无效:
#include <stdio.h> /*works*/
#include <type.h>
char *reserved[] = {
#include <stdio.h> /* doesn't work */
#include <ctype.h>
char *reserved[] = {
因此,函数从输入中获取一个字,并检查它是否是保留字。如果是,则将其添加到变量数组中,但如果它不是保留字,则再次运行该函数:
for(w = word, r = reserved; *r!= NULL; w=word, r++) /* Go to the next reserved word*/
for (; *w == **r; (*r)++, w++) /* check if the reserved word matches the word */
if (*w == ' ') { /* if it does, what follows is a variable */
getchar(); /* get the space */
for (v = var, (c=getchar()) =='*'? c = getchar(): c; c != ';' && c != '['; *v = ' ', c = getchar())
*v++ = c; /* add the variable to the variable array */
return var; /* return start of variable array */
}
if ((isalpha(*var)) == 0) { /* if variable array is empty, recursively run the function */
var = getvar(var, reserved);
}
当程序检查输入ctype
时,*r
会递增,因为ctype
的第一个字符和char
保留字的第一个字符匹配。但是单词不匹配,函数这次再次运行,检查输入char
。当再次调用保留函数时,指针r
设置为保留函数的开头:
for(w = word, r = reserved; *r!= NULL; w=word, r++)
所以**r
应该指向char
保留字的字符c
,但它指向char
的h
。
您能否解释一下,为什么指针没有指向开头,即使我只是将其设置为指向数组的开头,当我说r = reserved
时。
如果您想通过调试器运行它,我已经附加了下面的代码。
#include <stdio.h>
#include <ctype.h>
char *getvar(char *var, char *reserved[]);
int main() {
char var[100]; /* stored a variable */
char *v; /* pointer to the start of variable array variable */
char *reserved[] = {
"char", NULL
};
v = getvar(var, reserved); /* returns the start of a variable array */
printf("%s", v); /* prints the variable*/
return 0;
}
char *getvar(char *var, char *reserved[])
{
int c; /* a character*/
char *v, *w, **r; /* a variable, word, and a reserved word character*/
char word[100]; /* an array with a word */
while(((isalpha(c = getchar())) == 0) && c != EOF ); /* skip till you get to a name */
for(w = word; c != ' ' && c!='n' && c!='t' && c != EOF; c=getchar(), *w = ' ')
*w++ = c; /* add name to a word */
for(w = word, r = reserved; *r!= NULL; w=word, r++) /* Go to the next reserved word*/
for (; *w == **r; (*r)++, w++) /* check if the reserved word matches the word */
if (*w == ' ') { /* if it does, what follows is a variable */
getchar(); /* get the space */
for (v = var, (c=getchar()) =='*'? c = getchar(): c; c != ';' && c != '['; *v = ' ', c = getchar())
*v++ = c; /* add the variable to the variable array */
return var; /* return start of variable array */
}
if ((isalpha(*var)) == 0) { /* if variable array is empty, recursively run the function */
var = getvar(var, reserved);
}
return var; /* return start of variable array */
}
您的代码逻辑过于复杂,这使得此函数很难调试... 程序的逻辑p中也存在许多错误,这使得无法按原样调试。 我的意思是,修复此指针错误(或错误)无法使该程序立即运行......
您要遵守的第一条规则是,程序是简单算法的集合,分为函数,您可以将这些函数组合成更复杂的算法。
例如:
// You want to write functions that only do one thing at a time, this will
// make both your life and the reader's life a much more pleasant experience.
//
// This function reads a word from standard input
// params:
// - word: work buffer to hold result.
// - max_length: number of bytes in work buffer.
// returns:
// - the address of buffer 'word'
// - NULL on error
//
const char* read_input(char* word, int max_length)
{
// get a word:
// 1. skip until first alpha char, if EOF function FAILS (used to exit program)
// 2. read until first non-alpha char (EOF implicitely included)
char* w = word;
while (!isalpha(*w = getchar())
if (*w == EOF)
return NULL;
while (isalpha(*(++w) = getchar())
if (w >= word + max_length - 1)
return NULL; // We're overflowing our storage space !!!
// You may want to print an error message here.
*++w = 0; // NULL terminate the string.
return word; // we're successful
}
// this function looks for word pointed to by 'word' in
// NULL terminated array 'keywords'
//
// returns:
// - if successful returns value of pointer 'word'.
// - if failed, returns NULL
//
const char* find_keyword(const char* word, const char** keywords)
{
// Loop through array
// compare strings
// return immediately when found
while (*keywords)
{
if (strcmp(word, *keywords) == 0)
return word;
++keywords;
}
return NULL;
}
int main()
{
char word[100];
const char* w, *kw;
const char *reserved[] = { "char", NULL };
// 1. get next keyword from input, if NULL, exit.
// 2. check if it is a reserved keyword.
// 3. give some visual feedback.
while ((w = read_input(word, sizeof(word))) != NULL)
{
kw = find_keyword(w, reserved);
if (kw)
printf("%sn", kw);
else
printf("keyword '%s' not found!n", w);
}
return 0;
}
请注意,避免关注会使代码更易于编写和调试。 它还消除了不必要的复杂且容易出错的指针算法。
注意:此代码仅用于说明。 我还没有编译它,没有运行它,但它应该相当接近你想要实现的目标。 如果由于某种原因无法使用 strcmp,比较 2 个字符串是一个非常容易和直接的函数,只要您将其与其余代码隔离即可。