这是我的c程序的一部分。
cmdline = "ls | sort -r "
char * cmd1 = strtok(cmdline, "|");
char * cmd2 = strtok(NULL, "");
sscanf(cmd1,"%s",cmd1);
sscanf(cmd2,"%s",cmd2);
我试图得到输出为
cmd1 = "ls"
cmd2 = "sort -r"
但是我得到的输出是
cmd1 = "ls"
cmd2 = "sort"
我发现sscanf函数使"- "消失。但我不知道该怎么修剪。Sort -r "变成"sort - "还有"Sort -r -r "变成"sort -r -r">
我试着
sscanf(cmd2, "%s %s %s", cmd3, cmd4, cmd5);
但是它不能做到这一点,因为元素的数量是固定的。
那么我能做什么来解决这个问题呢?
当使用strtok
时,您必须确保您要标记的字符串是可变的,因为strtok
用NUL字节覆盖分隔符字符,在现有内存中形成标记。
例如,了解这两个对象之间的区别是很重要的:
const char *immutable = "pointer to a string literal.";
char mutable[] = "a character array, initialized by a string literal.";
要修剪前导空间,可以找到第一个非空格字符,并将其和所有后续字符移到前面。strspn
(和strcspn
)是查找span字符的有用函数。或者,在这种情况下,您可以移动指针,直到它指向第一个非空格字符。但是,当您需要保留基指针时(例如,传递给free
),此策略不起作用。
要修剪尾随空间,可以从字符串末尾开始,向后工作直到找到第一个非空格字符,并在之后放置一个NUL终止字节。
这是一个基本的修剪函数的例子。
注意,在本例中,tokens
的内容与cmd
具有相同的生存期。另外,trim
不压缩字符串中的空白(例如sort -r
)。
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#define MAX_TOKENS 8
char *trim(char *s) {
size_t i = 0;
size_t ll = strspn(s, " ");
if (ll) {
while (s[ll])
s[i++] = s[ll++];
s[i] = ' ';
} else
i = strlen(s);
while (i && s[i - 1] == ' ')
i--;
s[i] = ' ';
return s;
}
int main(void) {
char cmd[] = "ls | sort -r| foo | | bar ";
char *tokens[MAX_TOKENS];
char *tok;
size_t n = 0;
tok = strtok(cmd, "|");
while (n < MAX_TOKENS && tok) {
tokens[n++] = trim(tok);
tok = strtok(NULL, "|");
}
for (size_t i = 0; i < n; i++)
printf("%zu:[%s]n", i, tokens[i]);
}
输出:
0:[ls]
1:[sort -r]
2:[foo]
3:[]
4:[bar]