C中没有标准函数来获取字符串,在空格中将其分解
或其他分隔符,并在一步中创建指向char
的指针数组。
如果你想做那种事情,你也必须自己做
完全用手,或通过呼叫,例如循环中strspn
和strpbrk
,
或者在循环中调用strtok
,或者在循环中调用strsep
。
我不是在问这个怎么做。我know how to do this, 并且有plenty个 other questions 在Stackoverflow上 关于如何做到这一点。我问的是,是否有任何好的理由为什么 没有这样的功能。
我知道两个主要原因,当然:“因为没有主流的编译器/库 曾经有一个“和”因为C标准没有指定一个(因为 它喜欢标准化现有的做法。“但还有其他原因吗? (有这样的论据认为这样的功能是一个积极的坏主意吗?)
我知道,这通常是一种蹩脚而毫无意义的问题。在这种情况下 我很注意它,因为方便的分裂是非常有用的 操作。我在第一年内写了自己的字符串分割器 我认为C程序员,对我来说这是一个巨大的生产力提升器 以来。每天都有很多关于SO的问题 如果有的话,很容易回答(或者甚至不需要问) 标准分割功能,每个人都可以使用和参考。
要清楚,我想象的功能会有像
这样的签名int split(char *string, char **argv, int maxargs, const char *delim)
它会将string
分解为最多maxargs
个子字符串,从delim
分割一个或多个字符,将指针放入argv
,并修改{ {1}}在此过程中。
为了阻止一个论点,我相信有人会做出来:尽管它是标准的,我不会考虑
string
是一个有效的解决方案。坦率地说,strtok
很糟糕。说“你不需要拆分功能,
因为strtok
存在“很像是说”你不需要strtok
,
因为printf
存在。“这不是一个关于什么是理论上的问题
可以使用给定的工具集;这是有用和方便的。更多
我想,这里的根本问题涉及所涉及的不可言喻的权衡
选择可以提高利用率和提高生产力的工具
“付钱”。 (我认为很明显是一个很好的封装
字符串分割功能会很好地付出代价,但也许
那只是我。)
答案 0 :(得分:1)
我会尝试一个答案。我确实同意这样的功能是有用的。 通常在有一个语言的语言中非常有用。
基本上,您建议在strtok()
或strtok_r()
周围使用内置非常简单的包装器。它将是一个功能较弱的版本(因为我们无法在处理时更改分隔符),但在某些情况下仍然有用。
我看到的是,这些案例也与scanf()
家庭功能用例和getopt()
或getsubopt()
家庭功能用例重叠。
实际上,我不确定剩下的真实用例是那么常见。
在现实生活中,你需要一个真正的解析器或正则表达式库,在专门的常见情况下你已经有scanf()
或getopt()
甚至strtok()。
还可以修改他们的输入字符串,例如strtok()
,或者你的这些日子或多或少被弃用(经验说它们容易导致麻烦)。
大多数提供拆分功能的语言都有一个真正的字符串类型,通常是不可变的,并且通过创建许多单独的子字符串来保持原始字符串完整而支持它。
遵循该路径将导致某些其他API非基于零分隔字符串(可能具有开始指针和结束指针),或者使用分配的字符串副本(如使用strdup()
时)。两者都不令人满意。
最后,如果你在现实生活中加起来并不常见,编写起来非常简单,而不是那么简单或直观的API,毫无疑问这样的功能并没有包含在libard中。
基本上我会写这样的东西:
#include <string.h>
#include <stdio.h>
int split(char *string, char **argv, int maxargs, const char *delim){
char * saveptr = 0;
int x = 0;
argv[x++] = strtok_r(string, delim, &saveptr);
while(argv[x-1] && (x <= maxargs)){
argv[x++] = strtok_r(0, delim, &saveptr);
}
return x-1;
}
int main(){
char * args[10];
{
char * str = strdup("un deux trois quatre cinq six sept huit neuf dix onze");
int res = split(str, args, sizeof(args)/sizeof(char*), " ");
printf("res = %d\n", res);
for(int x = 0; x < res ; x++){
printf("%d:%s\n", x, args[x]);
}
}
{
char * str = strdup("un deux trois quatre cinq");
int res = split(str, args, sizeof(args)/sizeof(char*), " ");
printf("res = %d\n", res);
for(int x = 0; x < res ; x++){
printf("%d:%s\n", x, args[x]);
}
}
}
我看到的代码是使用strtok()
编写所需函数非常简单...并且使用结果的调用站点几乎与函数本身一样复杂。因此,在这种情况下,我宁愿在调用网站上内联函数而不是调用libc。
但是如果您认为对您来说更简单,那么欢迎您使用并撰写您的文章。