我正在C11中实现Shell,我想在进行系统调用以执行命令之前检查输入的语法是否正确。我要防止的可能输入之一是仅由空格字符组成的字符串。检查字符串是否仅包含空格,制表符或任何其他空格字符的有效方法是什么?
解决方案必须在C11中,最好使用标准库。使用readline()
中的readline.h
从命令行读取的字符串,并将其保存在char数组(char[]
)中。到目前为止,我想到的唯一解决方案是遍历数组,并用char
检查每个单独的isspace()
。有没有更有效的方法?
到目前为止,我想到的唯一解决方案是循环遍历数组,并使用
isspace()
检查每个单独的字符。
听起来不错!
有没有更有效的方法?
不是。如果要确保仅存在空格,您需要检查每个字符。 可能有一些技巧,涉及位掩码以更快的方式检测非空格字符(like strlen()
does查找NUL终止符),但是我绝对会建议[[not建议。
strlen()
检查返回的值,但是肯定会比较慢,因为这些功能是要在任意接受/拒绝字符串上工作的,并且需要首先建立查找表,而strspn()
or strcspn()
已针对其优化目的是使用预先建立的查找表,并且很可能还会由编译器使用适当的优化标志来内联。除此之外,代码strspn()
似乎是进一步加快速度的唯一方法。用strcspn()
编译(另请参见isspace()
)并运行一些基准测试。与-O3 -march=native -ftree-vectorize
相比,这样做的时间微不足道。
如果您需要比您的shell更为复杂的匹配(例如,使用引号进行参数设置),最好编写一个小的标记生成器/词法分析器。 strtok方法基本上是查找您指定的所有分隔符,将其临时替换为\ 0,返回子字符串到该点,将旧字符放回原处,并重复直到到达字符串末尾。
编辑:正如忙碌的蜜蜂在下面的注释中指出的那样,strtok不会放回它替换为\ 0的字符。上一段用词不好,但是我的目的是解释如果需要的话如何实现自己的简单标记器/词法分析器,而不是确切地解释strtok如何工作到最小的细节。