我正在尝试使用 strtok 分解包含管道 (|) 和 OR 符号 (||) 的 shell 命令,这些管道在数组中表示为字符,但 OR 命令也可以是旁边的两个管道彼此。具体来说,我需要知道什么时候 |、;、&& 或 ||显示在命令中。
有没有一种方法可以指定 strtok 中一个分隔符的结束位置和另一个分隔符的开头位置,因为我知道分隔符通常只有一个字符长,您只需将它们全部列出来,中间没有空格或任何内容。
哦,换行符是有效的分隔符吗?或者strtok只处理空格?
最佳答案
从上一个问题开始:是的,strtok
可以使用换行符作为分隔符,没有任何问题。
不幸的是,你的第一个问题的答案并不是那么积极。 strtok
将所有分隔符视为相等,并且不区分单个分隔符和任意数量的连续分隔符。换句话说,如果您将 |&;
作为分隔符,它将处理 |||||||||
或 &&&
或 &|&|;
完全相同。
我会更进一步:我会冒险并声明一个事实,strtok
根本不适合将 shell 命令分解为组成部分 - 我'我很确定没有办法将它用于这项工作来产生可用的结果。
特别是,您没有任何仅仅充当分隔符的东西。出于您的目的,&
、|
和 ||
是它们自己的标记。在提供给 shell 的字符串中,您不一定有任何东西符合 strtok
“思考”它们的方式作为分隔符。
strtok
面向由分隔符分隔的标记,这些分隔符除了分隔符之外什么都没有。当 strtok 读取标记时,它们之间的分隔符将被完全忽略(并且就此而言,被销毁)。对于 shell,像 a|b
这样的字符串实际上是三个标记 - 您需要 a
、|
和 b
—— 它们之间没有任何东西是 strtok
可以安全地覆盖和/或忽略的 —— 但这是 strtok
工作方式的要求。为了给您提供第一个 a
,它会用 '\0'
覆盖下一个字符(在本例中为 |
)。然后它无法恢复该管道来告诉您下一个标记应该是什么。
我认为您可能需要一个贪婪的分词器,即构建可以作为分词的最长字符串的分词器,并在遇到不能成为当前分词一部分的字符时停止。当您请求下一个标记时,它从前一个标记结束后的第一个字符开始,而不会(必然)跳过/忽略任何内容(当然,如果它遇到诸如未引用的空格之类的内容)不知何故,它可能会跳过它)。
关于C - 澄清 strtok 中的分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14351038/