C 在自定义shell中处理参数
我目前正在开发一个用C实现的shell,用于我希望随着时间的推移构建的类,但在执行我的参数时遇到了问题。我的程序使用C 在自定义shell中处理参数,c,memory,exec,argv,C,Memory,Exec,Argv,我目前正在开发一个用C实现的shell,用于我希望随着时间的推移构建的类,但在执行我的参数时遇到了问题。我的程序使用getchar()将条目解析到参数数组中,然后使用execvp()执行参数。我遇到的问题是重复输入参数,任何后续较短的参数都会与内存中某个地方的字符连接。下面的例子。我需要使用getchar,这就排除了获取参数的其他方法 //Global Variables char argument[64]; char **argv; int main(int argc, char
getchar()
将条目解析到参数数组中,然后使用execvp()
执行参数。我遇到的问题是重复输入参数,任何后续较短的参数都会与内存中某个地方的字符连接。下面的例子。我需要使用getchar
,这就排除了获取参数的其他方法
//Global Variables
char argument[64];
char **argv;
int main(int argc, char** argv) {
mainloop(); //Loop that calls the commands
return (EXIT_SUCCESS);
}
void prompt(){ //Modular prompt
printf ("?:");
}
void mainloop(){ //Loop that calls the functions
while(1){
prompt();
argv = (char**)malloc(sizeof(char*)*64); //allocate memory for argv
getcommand(argument, argv);
if((strcmp(argv[0],"exit" )) == 0){ //check for exit
return 0;
}
executecommand();
printcommand();
//clearcommand();
//printcommand();
}
}
void getcommand(char* argument, char** argv){ //Parser for the command
int i=0,j=0;
char c;
char* token;
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
token = strtok(argument, " ,."); //tokenize the command
while (token != NULL){
argv[j] = token; //pass command to array of arguments
token = strtok(NULL, " ,.");
j++;
}
//argv[j] = "\0";
}
void executecommand(){ //Function to call fork and execute with errors
pid_t childpid = fork();
int returnStatus;
if(childpid == -1){ //Fail to Fork
printf("failed to fork");
exit(1);
}
else if(childpid == 0){ //Child process
if (execvp(*argv, argv) < 0){
printf("error executing\n");
exit(1);
}
else{ //Execute successful
printf("executed");
}
}
int c=(int)waitpid(childpid, &returnStatus, 0);
if (returnStatus == 0) // Verify child process terminated without error.
{
printf("The child process terminated normally. \n");
}
if (returnStatus == 1)
{
printf("The child process terminated with an error!.\n");
}
//realloc(argv,64);
}
void printcommand(){ //Test function to print arguments
int i = 0;
while(argv[i] != NULL){
printf("Argv%d: %s \n",i, argv[i] );
i++;
}
}
/*void clearcommand(){ //Function to clear up the memory, does not work
int i=0;
argv[0] = " \0";
argv[1] = " \0";
}*/
任何短于前一个条目的条目都是如此。我不明白exec为什么在
'\0'
之后继续读取参数,我确信我在这里犯了内存错误。非常感谢您的帮助,我已经在这个问题上纠缠了几天了。您需要用包含空指针的元素指示argv
数组的结尾。注释掉的行:
argv[j] = "\0";
应该是:
argv[j] = NULL;
您还需要在参数
字符串的末尾放置一个空终止符。执行echo
时,您将得到l
,因为参数仍然包含上一个命令行。因此,第一行将参数设置为:
ls -l
然后用echo
覆盖前4个字符,使其变为:
echol
因此,全部功能将是:
void getcommand(char* argument, char** argv){ //Parser for the command
int i=0,j=0;
char c;
char* token;
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
argument[i] = '\0';
token = strtok(argument, " ,."); //tokenize the command
while (token != NULL){
argv[j] = token; //pass command to array of arguments
token = strtok(NULL, " ,.");
j++;
}
argv[j] = NULL;
}
您也可以使用fgets()
读取一行输入,而不是自己调用getchar()
您还应该检查输入是否大于参数的大小您需要用包含空指针的元素指示argv
数组的结尾。注释掉的行:
argv[j] = "\0";
应该是:
argv[j] = NULL;
您还需要在参数
字符串的末尾放置一个空终止符。执行echo
时,您将得到l
,因为参数仍然包含上一个命令行。因此,第一行将参数设置为:
ls -l
然后用echo
覆盖前4个字符,使其变为:
echol
因此,全部功能将是:
void getcommand(char* argument, char** argv){ //Parser for the command
int i=0,j=0;
char c;
char* token;
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
argument[i] = '\0';
token = strtok(argument, " ,."); //tokenize the command
while (token != NULL){
argv[j] = token; //pass command to array of arguments
token = strtok(NULL, " ,.");
j++;
}
argv[j] = NULL;
}
您也可以使用fgets()
读取一行输入,而不是自己调用getchar()
您还应该检查输入是否大于参数的大小
在读取输入行的循环之后,您需要使用NUL字符终止该行
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
argument[i] = '\0'; // <<---- terminate the input line
while((c=getchar())!='\n'){//获取字符并检查行尾
参数[i]=c;
i++;
}
参数[i]='\0';// 在读取输入行的循环之后,需要使用NUL字符终止该行
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
argument[i] = '\0'; // <<---- terminate the input line
while((c=getchar())!='\n'){//获取字符并检查行尾
参数[i]=c;
i++;
}
参数[i]='\0';//如果你能向我解释为什么使用全局变量…我已经编辑了你的问题。您对“C shell”的引用可能会令人困惑;它通常指现有的csh
shell。使用原型!不要在C中使用malloc
&friends!我根据你的建议删除了全局变量,谢谢Keith,我没有意识到这一点!如果你能向我解释为什么使用全局变量…我已经编辑了你的问题。您对“C shell”的引用可能会令人困惑;它通常指现有的csh
shell。使用原型!不要在C中使用malloc
&friends!我根据你的建议删除了全局变量,谢谢Keith,我没有意识到这一点!谢谢你这么清楚的解释!我完全忽略了争论这个问题。谢谢你这么清楚的解释!我完全忽略了争论这个问题。