[英]What is the best way to read a string as a command with a whitespace separated argument?
I'm currently writing a primitive shell that lets user input few basic commands: ls
, cat
etc. I'm taking from the user an input like: ls /home/someUser/someDirectory
and storing this in a character array, say input
. 我目前正在编写一个基本的外壳程序,该外壳程序让用户输入一些基本命令:
ls
, cat
等。我从用户那里获得一个输入: ls /home/someUser/someDirectory
并将其存储在一个字符数组中,例如input
。 I've written a few little such functions ls
, cat
etc. that take an argument and print to stdout
the expected result. 我已经写了一些这样的函数
ls
, cat
等,它们带有一个参数并打印以stdout
预期的结果。
What I'd like to know is: what would be the best way to break this input
up into a command and argument? 我想知道的是:将
input
分解为命令和参数的最佳方法是什么? For the said example, I'd like to get two different chunks: ls
and /home/someUser/someDirectory
, so that I can check what command the user wants to execute with what argument. 对于上述示例,我想获得两个不同的块:
ls
和/home/someUser/someDirectory
,以便可以使用什么参数检查用户要执行的命令。 Sure, I can maintain pointers and check the first few characters of the array and compare them and then proceed to the character after whitespace and parse the argument accordingly, but that would be very tedious and inefficient. 当然,我可以维护指针并检查数组的前几个字符并进行比较,然后进行空格之后的字符并相应地解析参数,但这将非常繁琐且效率低下。 Is there a better way to do this, possibly an in-built function?
有没有更好的方法可以做到这一点,可能是内置功能?
Thanks in advance. 提前致谢。
You could try using strtok
: 您可以尝试使用
strtok
:
#include <string.h>
#include <stdio.h>
int main(){
char example_input[80] = "ls /home/user/directory/file.ext";
const char s[2] = "-";
char *token = strtok(example_input, " ");
/* walk through other tokens */
while( token != NULL ){
printf("%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
Escape characters will be somewhat trickier. 转义字符会有些棘手。
If you only need to divide the string into command and argument this may work: 如果只需要将字符串分为命令和参数,则可以使用:
#include <string.h>
#include <stdio.h>
void cmd_ls(const char *arg){
printf("lsing %s\n",arg);
}
void cmd_pwd(const char *arg){
printf("pwding %s\n",arg);
}
int main(){
char example_input[80] = "psdwd /home/user/directory/file.ext";
const char s[2] = "-";
//Find command, assuming it ends at the first space
//Points to first space in string, will eventually point to beginning of
//command
char *command = strchr(example_input, ' ');
//Will point to beginning of argument
char *argument = NULL;
//If command is not NULL, then there is at least one space, so the string has
//the form "<COMMAND> X" where X is either '\0' (string terminator) or another
//character. If the string contains a space, edit it so that there is a
//terminator after the command. If there is an argument, return a pointer to
//its beginning (which may be a space).
if(command!=NULL){
*(command) = '\0'; //Terminate command string
if(*(command+1)!='\0') //If there are argument characters, point to them
argument = command+1;
}
command = example_input; //Point command to beginning of command
//Do I recognise this command?
if(strcmp(command,"ls")==0){
cmd_ls(argument);
} else if(strcmp(command,"pwd")==0) {
cmd_pwd(argument);
} else {
printf("Unrecognised command!\n");
}
return(0);
}
Check this out 看一下这个
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **split(char *const source, const char *const delimiter)
{
size_t length;
char **list;
size_t count;
char *pointer;
char *token;
void *saved;
if ((source == NULL) || (delimiter == NULL))
return NULL;
list = NULL;
pointer = source;
count = 0;
while ((token = strtok(pointer, delimiter)) != NULL)
{
saved = realloc(list, (1 + count) * sizeof(*list));
if (saved == NULL)
goto abort;
length = strlen(token);
list = saved;
list[count] = malloc(1 + length);
if (list[count] == NULL)
goto abort;
strcpy(list[count], token);
pointer = NULL;
count++;
}
saved = realloc(list, (1 + count) * sizeof(*list));
if (saved == NULL)
return list;
list = saved;
list[count] = NULL;
return list;
abort:
while (count != 0)
free(list[count--]);
free(list);
return NULL;
}
int main()
{
size_t k;
char string[] = "example string with spaces";
char **list;
list = split(string, " ");
if (list == NULL)
return -1;
k = 0;
while (list[k] != NULL)
{
printf("%s\n", list[k]);
free(list[k]);
k++;
}
free(list);
return 0;
}
The split function will return an array of char
pointers which contain the tokens, and have a sentinel NULL
pointer that tells you where the end of the list is. split函数将返回一个包含指针的
char
指针数组,并具有一个前哨NULL
指针,该指针告诉您列表的结尾在哪里。
you can do it simply using scanf. 您可以简单地使用scanf做到这一点。 you have to read the input until you get a '\\n' character.
您必须先阅读输入内容,直到获得'\\ n'字符为止。 the code to do it will be :
要做的代码是:
scanf("%[^\n]", string);
the total string will be stored in the array string. 总字符串将存储在数组字符串中。 you can do further string processing to extract the required data.
您可以进行进一步的字符串处理以提取所需的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.