在C语言中解析空格分隔的文本

3
我正在为学校项目编写一个程序,旨在以非常基本的形式模拟Unix shell。它基本上是解析输入,然后进行fork / exec。我需要能够单独读取程序中的参数(而不是作为从命令行传递给程序的参数)。例如,我会提示:

请输入一个命令:

...我需要能够解析这两个参数...

ls

或者

ls -l

但问题在于似乎没有简单的方法来实现这一点。scanf()会分别拉取每个参数,但我没有找到将它们放入 char* 数组中不同插槽的方法。例如,如果我执行以下操作...

char * user_input[10];
for (int i=0; i<10; i++){
    user_input[i] = (char *) malloc(100*sizeof(char));
}

for (int i=0; *(user_input[i]) != '@'; i++)
{
    scanf("%s", user_input[index]);
    index++;
}

如果输入是"ls -l",那么user_input[0]将得到"ls",然后循环将重新开始,user_input[0]将得到"-l"getsfgets只会获取整行。显然,这个问题可以通过逐个提取每个参数来逻辑上解决...但如果有一个我错过的简单方法,我想避免这样做。有吗?
谢谢!

由于这被标记为作业,也许使用 strtok 会有帮助? - JUST MY correct OPINION
4个回答

7

如果您的用例足够简单,您可以使用strtok实现:

char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);

strtok()函数将字符串解析成一个标记序列。在第一次调用strtok()时,应该在str中指定要解析的字符串。在每次后续调用中应该解析相同的字符串,str应该为NULL

您可以使用strtokstrtok_r来按空格拆分字符串。

如果您正在进行更复杂的操作,其中一些参数可能带有(带引号的)空格,则基本上需要自己进行解析 - 尽管您可以查看shell(例如bash)的源代码以查看其如何处理此类情况。

kilanash友善地提醒我显而易见的遗漏 - GNU getopt。但是,您仍然需要先将其解析为单独的参数。


1
getopt是相当著名的GNU标准库。 http://www.gnu.org/s/libc/manual/html_node/Parsing-Program-Arguments.html - Kilanash
@Kilanash:哦,傻瓜。我已经用了十几次,不知道为什么没有把它放在我的答案中。当然…… getopt 在 argv 上工作 - 当它们到达 getopt 时,shell 已经将参数分割开了。因此,这更像是一个第二步,在 OP 所询问的初始分割之后。 - Cascabel
谢谢。这看起来会起作用...这是一个非常基本的shell模拟器,所以我不认为我需要担心引号空格。感谢您的帮助! - rybosome

2

忘记 scanf 的存在,因为它很少做你想要的事情。一次获取整行内容,然后编写代码将其拆分。 strtok——这个问题的第二受欢迎的答案——也存在问题。


对于作业问题呈现的典型简单用例,strtok通常已经足够了。尽管我不认为曾经看到过scanf被很好地使用过,但你因为说“避免使用scanf”而获得了+1。 - JUST MY correct OPINION
足够,肯定。会教坏习惯吗?可能。 - msw

1

您可以使用strtok_r函数来按空格分割字符串。请注意,这是一种破坏性操作(会修改输入的字符串)。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接