今天看了一下午的 C Primer Plus 就只为了看字符串这部分,因为总是觉得自己这部分太差了。
从pascal转来之后就没有好好地学习字符串操作……这不对……
于是对我平时做题造成了挺大麻烦……
好,抽出public holiday的一下午,好好看看这本bible~
主要还是研究一下string functions
表示
/*我把这部分忽略了*/
String Input
1.首先就是读入,平常最经常使用的 scanf作用就是get a word 而不是 get a string。 即便得到了一个string……呵呵……其中"_"代表空格scanf("%s", name); /*Fleebert Hup*/ /*name: Fleebert*/ /*remaining: _Hup*/ scanf("%5s", name); /*Fleebert Hup*/ /*name: Fleeb*/ /*remaining: ert_Hup*/ scanf("%10s", name); /*Fleebert Hup*/ /*name: Fleebert*/ /*remaining: _Hup*/
2.其次要说的是很方便的gets()读取一个string,以"\n"为停止标志,同时忽略这个newline
3.文件输入fgets()
因为gets()有个weakness, it doesn't check to see whether the input actually fits into the reserved storage area. Extra characters simply overflow into the adjoining memory.这个东西竟然成了一个UNIX的"warm",把我吓尿了……所以我们便使用更保险的fgets().不过这个东西是为文件输入输出而设计的。
注意,这里跟gets()不同之处在于,fgets()并不忽略末尾的"/n"(估计是只在乎EOF),之后输出部分,我会再提到。
#define SIZE 81 char name[SIZE]; char *ptr; ptr = fgets(name. SIZE, stdin);
1.对应着来,先说printf就这样,还是比较简单的。printf("%s\n", string); /* <=> puts(string)*/ printf("yeah");
不过要注意的是printf是不会自动添加newline的,所以gets得到的string,一定要记得加"\n".2.接下来是puts很简单的代码,我就不写了。要注意的是,恰好跟gets对应,puts是自动添加newline的~这就恰好可以使用while (gets(line)) puts(line);
有一个比较严重的问题,那就是puts停下来的符号是"\0".如果是下面这个代码/* nono.c -- no! */ #include <stdio.h> int main(void) { char dont[] = {'W', 'O', 'W', '!' }; puts(dont); /* dont is not a string */ return 0; }
就会发生奇怪的事情了……为什么?因为dont不是一个string,他是一个char的array。是不是略乱?呵呵……总之,这样写,puts会一直查找memory,直到遇到一个"\0".
然后我就突然明白了……string和array of characters3.最后,依旧是保险版的puts,fputs()因为fgets,不忽略newline,那么fputs自然也就不能再添加了~~人家是一对儿嘛!所以while (fgets(line, SIZE, stdin)) fputs(line, stdout);
String Function
1.strlen 比较简单哈
2.strcat 把第二个arg加到第一个arg上,return 第一个arg的value(也就是一个地址)
strncat 跟strcat很像,但是为了防止第二个赋值的时候出现错误(overflow之类的)总共带3个arg,前两个和strcat一样,最后一个表示第二个参数要加上去的长度。比如
int a[4] = "asdf"; char b[7] = "abcdefg"; int available = 3; strncat(a, b, available); printf("%s",a); //output: asdf\0abc
虽然在这里……我的compiler打出的是一个心……但是复制出来就是ETX了~(end of text)3.strcmp 比较两个字符串。
这里说明一下,如果单纯写 if (Str1 != Str2) 意思是如果Str1 和 Str2指针指向的不是同一个字符串,这显然不是我们的本意。所以要用这个函数。相同,return 0. Str1字典序数比Str2大,那就return 1 否则return 0。
同样,还有strncmp,有第三个arg,限制比较的长度。
4.strcpy就是copy喽~不是单纯的地址指针复制,而是创造了一个新的string。
这里有个地方我看了半天才明白的……上代码
ps = strcpy(copy+7, orig);
这句的意思就是,把orig全部放到*copy这个字符串的第七位及往后。若orig的长度不够,*copy的残余部分还在。当时我就在看,为什么ps代表的值是orig和copy的残余部分。原来,return 的值是第一个参数,也就是(copy+7)这个指针,那么ps自然是*copy从第7位开始的。
strncpy the careful choice 呵呵……
跟前面的几个的区别挺像的。嗯……多了一个第三arg,代表长度。
5.sprintf 这个函数好啊!当时学python我就想方设法把几个字符串和数字神马的加在一起……学了php,发现好用多了!那个小小的点"." 竟然那么强大……而且对于单引号双引号的区分比python好多了……
这个感觉就像是没有打印机……直接输出pdf文档一样啊……爽死了……
呵呵……扯远了……
sprintf(str, "%s, %-19s: %6.2f\n", last, first, money);
嗯……我就看了这么多……感觉系统的学一学还是相当重要的~
突然还是想到了pascal,想想陪伴了我那么多年,现在我碰都不碰它……真是蛮伤感的~
好了~这个不好看的学习笔记就先这样吧~哈哈~