检查字符串在C中是不是只有空格字符

Posted

技术标签:

【中文标题】检查字符串在C中是不是只有空格字符【英文标题】:Check if a string has only whitespace characters in C检查字符串在C中是否只有空格字符 【发布时间】:2020-02-04 02:26:35 【问题描述】:

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

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

【问题讨论】:

一个循环和一个switch 语句? 听起来像你想要的strspn 使用 strspn 可以节省我的打字时间,但我认为 for 循环更有效。 【参考方案1】:

到目前为止,我想到的唯一解决方案是遍历数组,并使用 isspace() 检查每个单独的字符。

听起来不错!

有没有更有效的方法?

不是真的。如果您想确保只有空格,您需要检查每个字符。 可能有一些技巧涉及位掩码以更快的方式检测非空格字符(like strlen() does 查找 NUL 终止符),但我绝对不会建议它。

您可以使用strspn() or strcspn() 检查返回值,但这肯定会更慢,因为这些函数旨在处理任意接受/拒绝字符串并且需要首先构建查找表,而isspace() 针对它的目的是使用预先构建的查找表,并且很可能还会由编译器使用适当的优化标志进行内联。除此之外,vectorization 的代码似乎是进一步加快速度的唯一方法。使用-O3 -march=native -ftree-vectorize(另见this post)编译并运行一些基准测试。

【讨论】:

【参考方案2】:

"循环遍历数组,并使用isspace() 检查每个单独的字符" --> 是的。

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

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

不,据我所知strtok() 不会 放回旧字符。它的结果是指向(当前)令牌的指针。

以上是关于检查字符串在C中是不是只有空格字符的主要内容,如果未能解决你的问题,请参考以下文章

检查字符串是不是只有字母和空格

如何检查字符串是不是包含字符和空格,而不仅仅是空格?

如何检查一个字符是不是等于一个空格?

检查字符串(句子空格分隔)以查看它是不是包含数组中的任何字符

如何检查第一个字符是不是在输入“C”的特定位置

如何省略字符串的点、逗号和空格(检查回文时需要)