检查一个字符串在 C 中是否只有空白字符

Check if a string has only whitespace characters in C

我正在 C11 中实现 shell,我想在执行系统调用以执行命令之前检查输入的语法是否正确。我想要防止的可能输入之一是仅由 white-space 字符组成的字符串。检查字符串是否仅包含白色 space、制表符或任何其他白色-space 字符的有效方法是什么?

解决方案必须在 C11 中,并且最好使用标准库。使用 readline()readline.h 从命令行读取的字符串,它保存在一个字符数组 (char[]) 中。到目前为止,我想到的唯一解决方案是遍历数组,并检查每个 charisspace()。有没有更有效的方法?

"loop over the array, and check each individual char with isspace()" --> 是的。

readline() 相比,这样做的时间微不足道。

So far, the only solution that I've thought of is to loop over the array, and check each individual char with isspace().

听起来不错!

Is there a more efficient way?

不是真的。如果您想确保只有 space 存在,您需要 检查每个字符。 可能有一些涉及位掩码的技巧可以更快地检测非space字符(找到NUL终止符),但我肯定会建议。

您可以使用 strspn() or strcspn() checking the returned value, but that would surely be slower since those functions are meant to work on arbitrary accept/reject strings and need to build lookup tables first, while isspace() is optimized for its purpose using a pre-built lookup table, and will most probably also get inlined by the compiler using proper optimization flags. Other than this, vectorization of the code seems like the only way to speed things up further. Compile with -O3 -march=native -ftree-vectorize (see also ) 和 运行 一些基准。

我将为您的问题提供替代解决方案:使用 strtok。它根据一组特定的忽略定界符将字符串拆分为子字符串。使用空字符串,您将根本得不到任何标记。

如果您需要比 shell 更复杂的匹配(例如,要使用引号),您最好写一个小的 tokenizer/lexer。 strtok 方法基本上只是查找您指定的任何分隔符,暂时将它们替换为 \0,返回到该点的子字符串,将旧字符放回原处,并重复直到到达字符串的末尾。

编辑: 正如 busybee 在下面的评论中指出的那样,strtok 不会放回它用 \0 替换的字符。上面的段落措辞不佳,但我的目的是解释如何在需要时实现您自己的简单 tokenizer/lexer,而不是解释 strtok 如何工作到最小的细节。