社区导航

 
查看: 326|回复: 12

[源码分析] 【C标准库里那些好玩的东西】strcoll:strcpy的表亲

[复制链接]

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

发表于 2017-8-11 00:22:16 | 显示全部楼层 |阅读模式
晚上在看昨天回复的一个帖子,楼主提到“合理使用库函数能否......”



其实有点小感动:还是有人愿意好好研究 C标准库。
因为我自己曾遇到不少人,对C标准库的了解程度和重视程度 低得让人无语。

他们曾说出以下言论:
1.线程锁 和 信号量 只有操作系统才有(甚至有人说只有windows才有)......

还有很多人,因为不知道其实 有 strstr 这些函数,要自己费尽去实现一次,还有人因为不知道其实是有 isalpha isdigit这些函数,还要想着用 ascii 分 0x41(A) 0x30(0)等等诸多方法自己实现一次......

但说到C标准库,好几年前,我一直困惑,所谓 标准C到底是什么?直到后来,我大致理解为 标准C 就是  某个版本的 ansi c标准 cxx + 一个符合该标准的 c compiler + 一个符合该标准的 C标准库。是为 标准C。

但说实话,对于C标准库,我一直只知道
#include <stdio> 然后就可以愉快的 printf("helloworld");

除此之外我一无所知,直到后来我知道它其实是一个安装在系统里某个地方的一套源码(准确的说是它编译好的库)。

那时候我还不知道原来所谓C标准库的源码也是要收钱的,但是不要紧,后来我知道了有一个叫做 glibc的东西(gcc开源的c标准库)。
我尝试下载过,结果,连怎么把它编译起来都不知道(因为我在windows下,没有make环境)

到后来,我偶然找到一本书,P.J.Plauge 写的一本 C标准库。
我终于找到一本那样的书:详细告诉我C标准库到底有什么,都是按照什么逻辑设计的.......

我真的硬着头皮把这本书看完,最后我得出的结论只有一个:
这书是送给 想要实现一个C标准库的人准备的,而对于要使用它的人,如你我中大多者来说,这书有点像 词典。

从那时起,我就明白了:
也许,我需要的更多的,只不过是 有一个代码,它很小很简单,但是通过实例,告诉我这个东东是干嘛的,是怎么用的(就是使用的时候要注意什么,C库的设计者希望你怎么使用,这很重要——因为没有任何一个函数是任人蹂躏都绝对不会出毛病,哪怕是大名鼎鼎的 C标准库)
此帖出自编程基础论坛
无历史,不传奇,不号召
初九,潜龙勿用

回复

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-11 00:23:47 | 显示全部楼层
闲话少说,我很久没回来坛子,发帖子了。
先贴上一段代码,我觉得很有意思。
因为,它提及了一个我们可能很多人都很陌生的函数

strcoll.

我在查阅资料时,发现它有一个很好玩的地方。可以对中文按照拼音排序。

我先把 代码贴上来,并且我会在我的win10上,codeblocks运行,测试一下。
但是,我更加感兴趣的是,它在我的MCU上跑起来,会是一个什么情况。
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-11 00:24:20 | 显示全部楼层
[C] 纯文本查看 复制代码
#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <locale.h>

int main (void)

{

    int i;

    char str[10][4]= {"镕","堃","趙","錢","孫","李","周","吳","鄭","王"};

    qsort (str, 10, 4, strcoll);

    printf ("按内码排序:");

    for (i=0; i<10; i++)

        printf ("%s", str[i]);

    setlocale (LC_ALL, "");

    qsort (str, 10, 4, strcoll);

    printf ("\n按音序排序:");

    for (i=0; i<10; i++)

        printf ("%s", str[i]);

    return 0;

}
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-11 00:30:37 | 显示全部楼层
无标题.png 从结果看,的确如此。

现在我有俩问题:
1.所谓内码是神马?你说英语我可能会猜测是 ascii吗。
但现在是中文,那么,到底是unicode还是 gb2312系列?
2.这个locale显然是C标准库的一部分,那么,按道理,单片机上面也应该没问题,问题是,单片机的C库是经过裁剪的么?
这里其实很有意思,比如 IAR KEIL里,其实你是可以选择不同版本的 库的
它们被命名为 normal full 什么鬼的,这到底是一些什么关系?

PS:相信我,文本处理真的很重要,哪怕是对于单片机,虽然我知道,好多人都很抵触在单片机上使用大量文本。
但是我自己的FreeUI 计划更新的下一版本,就是要采用 纯文本的 UI配置描述。

至于说中文嘛......
我们都是中国人,当然,要说中国话。
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

1552

TA的帖子

0

TA的资源

五彩晶圆(初级)

Rank: 7Rank: 7Rank: 7

发表于 2017-8-11 08:49:57 | 显示全部楼层
期待版主的后续内容,我之前也有想过能在MCU上使用的库函数是不是经过裁减的,或者使用上会有什么限制,比如内存大小

回复 支持 反对

使用道具 举报

24

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-8-11 08:52:14 | 显示全部楼层
好东西,学习学习。谢谢版主!

回复 支持 反对

使用道具 举报

144

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-8-11 09:37:58 | 显示全部楼层
output is differnent
[C] 纯文本查看 复制代码
admin@admin-PC MINGW64 ~/test
$

admin@admin-PC MINGW64 ~/test
$ cat aa.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
int main (void){
    int i;
    char str[10][4]= {"镕","堃","趙","錢","孫","李","周","吳","鄭","王"};
    qsort (str, 10, 4, strcoll);
    printf ("按内码排序:");
    for (i=0; i<10; i++)
        printf ("%s", str[i]);
    setlocale (LC_ALL, "");
    qsort (str, 10, 4, strcoll);
    printf ("\n按音序排序:");
    for (i=0; i<10; i++)
        printf ("%s", str[i]);
    return 0;}
admin@admin-PC MINGW64 ~/test
$ gcc aa.c -o aa.exe
aa.c: 在函数‘main’中:
aa.c:8:24: 警告:传递‘qsort’的第 4 个参数时在不兼容的指针类型间转换 [-Wincompatible-pointer-types]
     qsort (str, 10, 4, strcoll);
                        ^
In file included from /usr/include/stdio.h:29:0,
                 from aa.c:1:
/usr/include/stdlib.h:139:7: 附注:需要类型‘__compar_fn_t {或称 int (*)(const void *, const void *)}’,但实参的类型为‘int (*)(const char *, const char *)’
 _VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, __compar_fn_t _compar));
       ^
aa.c:13:24: 警告:传递‘qsort’的第 4 个参数时在不兼容的指针类型间转换 [-Wincompatible-pointer-types]
     qsort (str, 10, 4, strcoll);
                        ^
In file included from /usr/include/stdio.h:29:0,
                 from aa.c:1:
/usr/include/stdlib.h:139:7: 附注:需要类型‘__compar_fn_t {或称 int (*)(const void *, const void *)}’,但实参的类型为‘int (*)(const char *, const char *)’
 _VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, __compar_fn_t _compar));
       ^

admin@admin-PC MINGW64 ~/test
$ ./aa.exe
按内码排序:吳周堃孫李王趙鄭錢镕
按音序排序:堃李錢镕孫王吳趙鄭周
admin@admin-PC MINGW64 ~/test
$

点评

我在CB下试了试切换编码,开始是 windows965,后来我改成了 utf8 比你还惨,直接显示乱码,而且字数都不一样了。  详情 回复 发表于 2017-8-14 20:28
咦? 有意思诶...... 话说我的MINGW64都没装成功  详情 回复 发表于 2017-8-11 09:42

回复 支持 反对

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-11 09:42:05 | 显示全部楼层
EETUX 发表于 2017-8-11 09:37
output is differnent
[mw_shl_code=c,true]admin@admin-PC MINGW64 ~/test
$

admin@admi ...

咦?
有意思诶......
话说我的MINGW64都没装成功
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

144

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2017-8-11 10:06:25 | 显示全部楼层
本帖最后由 EETUX 于 2017-8-11 10:18 编辑

感觉跟.c是utf8还是ansi有关...
11111.PNG

点评

所以我想你是对的。  详情 回复 发表于 2017-8-14 20:28

回复 支持 反对

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-14 20:28:21 | 显示全部楼层
EETUX 发表于 2017-8-11 09:37
output is differnent
[mw_shl_code=c,true]admin@admin-PC MINGW64 ~/test
$

admin@admi ...

我在CB下试了试切换编码,开始是 windows965,后来我改成了 utf8
比你还惨,直接显示乱码,而且字数都不一样了。
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-14 20:28:35 | 显示全部楼层
EETUX 发表于 2017-8-11 10:06
感觉跟.c是utf8还是ansi有关...

所以我想你是对的。
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

7076

TA的帖子

48

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2017-8-14 20:34:07 | 显示全部楼层
晚上吃完饭回来人都跑光了,等到进来时折腾了快一个小时
下次再仔细研究 这个 国际化的 locale库。
涉及很多 iso 格式 的 编码,都不认识,没法看,今晚没时间了

点评

非常不错,我第一次听说这个函数,你好好研究,期待继续分享!  详情 回复 发表于 7 天前
无历史,不传奇,不号召
初九,潜龙勿用

回复 支持 反对

使用道具 举报

4898

TA的帖子

67

TA的资源

版主

Rank: 6Rank: 6

发表于 7 天前 | 显示全部楼层
辛昕 发表于 2017-8-14 20:34
晚上吃完饭回来人都跑光了,等到进来时折腾了快一个小时
下次再仔细研究 这个 国际化的 locale库。
涉及 ...

非常不错,我第一次听说这个函数,你好好研究,期待继续分享!
EEWORLD开发板置换群:309018200,——电工们免费装β的天堂,商家勿入!加群暗号:喵

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-8-24 11:04 , Processed in 1.455664 second(s), 16 queries , Redis On.

快速回复 返回顶部 返回列表