为什么在C中没有拆分函数? [英] Why no split function in C?

查看:57
本文介绍了为什么在C中没有拆分函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C中没有标准函数来获取字符串,在空格处将其拆分 或其他分隔符,并在一个步骤中创建指向char的指针数组。 如果你想做那种事,你也得自己做 完全手动或通过例如在循环中调用strspnstrpbrk, 或者在循环中调用strtok,或者在循环中调用strsep

我不是在问如何做到这一点。iknow how to do this, 并且有plentyotherquestions 关于堆栈溢出问题 关于如何做这件事。我想问的是有没有什么好的理由为什么 没有这样的函数。

我当然知道两个主要原因:&因为没有主流编译器/库 曾经有过&和&,因为C标准也没有指定一个(因为 它喜欢标准化现有的做法)。但还有其他原因吗? (是否有争论认为这样的函数是一个非常糟糕的主意?)

我知道,这通常是一个蹩脚而毫无意义的问题。在这种情况下 我之所以专注于它,是因为方便的拆分是非常有用的 手术开始了。我第一年就写了我自己的字符串拆分器。 C程序员,我想,这对我来说是一个巨大的生产力增强器 从那以后。这里有几十个问题,所以每天都有可能是 很容易回答(或者甚至不需要问),如果有 每个人都可以使用和引用的标准拆分函数。

明确地说,我想象的函数应该有一个签名,如

int split(char *string, char **argv, int maxargs, const char *delim)

它最多将string拆分为maxargs子字符串,拆分delim中的一个或多个字符,将指向子字符串的指针放入argv中,并在此过程中修改string

为了阻止争论,我相信有人会这样说:虽然这是标准做法,但我不认为 strtok成为有效的解决方案。strtok,坦率地说,很糟糕。说你不需要分裂函数, 因为strtokEXISTS&Quot;很像是说printf您不需要printf, 因为puts存在。&这不是理论上什么是 对于给定的工具集是可能的;它毗邻什么是有用的和方便的。就越多 我想,这里的根本问题是所涉及的不可言喻的权衡。 在挑选可利用和提高生产力的工具时, 支付他们的费用(&q;)。(我认为很明显,一个封装得很好的 字符串拆分函数会带来丰厚的回报,但也许 那只是我。)

推荐答案

我将尝试回答。我确实同意这样的功能是有用的。它在有它的语言中通常非常有用。

基本上,您建议在strtok()strtok_r()周围使用非常简单的内置包装器。它将是一个不太强大的版本(因为我们在处理时不能更改分隔符),但在某些情况下仍然有用。

我看到的是,这些案例还与scanf()家庭功能用例重叠,与getopt()getsubopt()家庭功能用例重叠。

实际上,我不确定其余的实际用例是否那么常见。

在现实生活中非常重要的情况下,您需要一个真正的解析器或正则表达式库,在特殊的常见情况下,您已经有scanf()getopt(),甚至strtok()。

还有函数修改它们的输入字符串,如strtok()或您的,这些天或多或少不受欢迎(经验表明它们很容易导致麻烦)。

大多数提供拆分功能的语言都有一个真正的字符串类型,通常是不变的,并且通过创建许多单独的子字符串来支持它,同时保持原始字符串不变。

沿着该路径将导致其他一些不基于零分隔符字符串的API(可能带有起始指针和结束指针),或者带有分配的字符串副本(就像使用strdup()时一样)。两者都不太令人满意。

归根结底,如果您把现实生活中不太常见的用法、相当简单的编写和不那么简单直观的API加在一起,难怪标准libc中没有包含这样的函数。

基本上我会这样写:

#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
", res);
        for(int x = 0; x < res ; x++){
            printf("%d:%s
", x, args[x]);
        }
    }

    {
        char * str = strdup("un deux trois quatre cinq");
        int res = split(str, args, sizeof(args)/sizeof(char*), " ");
        printf("res = %d
", res);
        for(int x = 0; x < res ; x++){
            printf("%d:%s
", x, args[x]);
        }
    }
}
我在代码中看到的是,使用strtok()编写所需的函数确实非常简单.并且使用结果的调用点几乎与函数本身一样复杂。在这种情况下,从今以后,我宁愿在调用点内联函数,也不愿调用libc。

但是,如果您认为这样对您更简单,当然欢迎您使用并编写您的。

这篇关于为什么在C中没有拆分函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆