gpt4 book ai didi

c - 如何为简单的命令行解释器解析 fgets 中的字符串以存储在 argv[] 中?

转载 作者:行者123 更新时间:2023-11-30 15:42:13 30 4
gpt4 key购买 nike

我正在尝试创建一个简单的 shell 程序,并使用 fgets() 从用户那里获取输入。我将用户输入存储在 char[] 中,然后尝试使用我编写的 getword() 方法对其进行解析。但是,我不知道如何获取 getword() 方法来解析字符串。我可以打印出命令行 char[] 并准确查看提示符下键入的内容,但它没有被解析。 getword() 返回相同的未解析字符串,并尝试将整个字符串存储在 argv[0] 中。我已经单独测试了 getword() 方法,它返回了我想要的结果。这是我当前的尝试:

主shell程序:

int main() {
pid_t pid, first, second;
mode_t fileBits;
size_t ln;
int argc, inputRedirect, firstStatus, i, execvpReturnVal;
int childOutput_fd;
long octalPermissionString;
char *home = getenv("HOME");
char *argv[MAXITEM];
char devNull[10] = "/dev/null";
char commandLine[STORAGE];
struct stat fileStats;

signal(SIGTERM, myhandler);

for (;;) {
background = 0;
printf("p2: ");
fflush(stdout);


/*---------FGETS PROMPT----------*/

fgets(commandLine, STORAGE, stdin);
commandLine[strlen(commandLine) - 1] = '\0';
printf("commandLine = [%s]\n", commandLine);
/*==============OTHER SHELL METHODS=============*/

调用 getword() 的 parse() 方法:

int parse(char *commandLine, char *argv[]) {
int argc = 0;
char *commandPointer;
argv[argc++] = commandLine;
printf("argv[%d] = [%s]\n", argc-1, commandLine);

do{
commandPointer = (char*)malloc(sizeof(char) * STORAGE);
argv[argc++] = commandPointer;
printf("argv[%d] = [%s]\n", argc-1, commandPointer);
getword(commandPointer);
}while(*commandPointer != '\0');
argc--;
argv[argc] = '\0';
return argc;

}

getword()解析方法:

/*Function Prototypes*/
int tilde(char *p, int i);
int isMeta(int thisChar);


int getword(char *w) {

int currChar, nextChar, offset;
int index = 0;
int *tildeHelper;

currChar = getchar();

while(currChar == ' ' || currChar == '\t') {
currChar = getchar();
}

if(currChar == EOF)
return -1;


switch(currChar) {
case '\0':
w[index] = '\0';
return index;
case '\n':
w[index] = '\0';
return index;
case ';':
w[index] = '\0';
return index;
case '<':
w[index++] = currChar;
w[index] = '\0';
return index;
case '>':
w[index++] = currChar;
if((nextChar = getchar()) == '>')
w[index++] = currChar;
else {
ungetc(nextChar, stdin);
}
w[index] = '\0';
return index;
case '|':
w[index++] = currChar;
w[index] = '\0';
return index;
case '&':
w[index++] = currChar;
w[index] = '\0';
return index;
case '~':
tildeHelper = &index;
index = tilde(&w[index], *tildeHelper);

default:
w[index++] = currChar;
while((currChar = getchar()) != ' ' && currChar != '<' && currChar != '>' && currChar != '|' && currChar != ';' && currChar != '&' && currChar != '\t' && currChar != '\n' && currChar != '\0' && currChar != EOF && index <= STORAGE - 1) {
switch(currChar) {
case '~':
tildeHelper = &index;
index = tilde(&w[index], *tildeHelper);
break;

case '\\':
nextChar = getchar();
if(metaCharacter(nextChar))
w[index++] = nextChar;
else {
ungetc(nextChar, stdin);
w[index++] = currChar;
}
break;

default:
w[index++] = currChar;
}
}
ungetc(currChar, stdin);
w[index] = '\0';
return index;
}
}


int tilde(char *cp, int i) {
int *ip = &i;
char *p = cp;
char *o;
o = (strcpy(p, getenv("HOME")));
int offset = strlen(o);
*ip = *ip + offset;
return i;
}

int metaCharacter(int thisChar) {
int isMeta = 0;
switch(thisChar) {
case '~':
isMeta = 1;
break;
case '<':
isMeta = 1;
break;
case '>':
isMeta = 1;
break;
case '|':
isMeta = 1;
break;
case ';':
isMeta = 1;
break;
case '&':
isMeta = 1;
break;
case '\\':
isMeta = 1;
break;
}
return isMeta;
}

最佳答案

您正尝试从 stdin 读取命令行两次。首先,使用 fgets() 读取整行,然后在 getword 中尝试使用 getchar() 获取下一个字符。实际上,这试图读取第二行。您应该读取包含该行的字符缓冲区。

更新您的 getword 函数以获取第二个参数 src,即要读取的行。然后将所有对 getline 的调用替换为 *src++:

int getword(char *w, const char *src) {

int currChar, nextChar, offset;
int index = 0;
int *tildeHelper;

currChar = *src++;
while(currChar == ' ' || currChar == '\t') currChar = *src++;

/* ... */
}

然后,您的 parse 函数必须将命令行传递给 getword 并使用 getword 的返回值来更新字符串位置:

int parse(char *commandLine, char *argv[])
{
int argc = 0;
int index = 0;

while (1) {
char *commandPointer = malloc(sizeof(char) * STORAGE);
index += getword(commandPointer, commandLine + index);
if (*commandPointer == '\0') break;
argv[argc++] = commandPointer;
}

return argc;
}

代码中仍然存在问题,例如无法正确获取 getword 的返回值并且未释放参数字符串。

此外,要实现 shell,请查看 getline,它是比普通的旧“fgets”更好的命令行输入界面。

关于c - 如何为简单的命令行解释器解析 fgets 中的字符串以存储在 argv[] 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20255245/

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