11-1:字符串表示和字符串I/O

  1.首先先通过一个整体的例子来初步了解建立,读入和输出字符串的几种方式。

#include<stdio.h>
#define MSG "你一定有很多智慧,告诉我一些吧!"
#define LIM 5
#define LINELEN 81
int main(){
char name[LINELEN];
char talents[LINELEN];
int i ;
const char m1[] = "Limit yourself to one line's worth. ";
const char m2[] = "If you can't think of anything,fake it. ";
const char *m3 = "\nEnough about me - what's your name? ";
const char *mytal[LIM] = {
"Adding numbers swiftly",
"MUltiplying accurately ",
"Stashing data",
"Following instructions to the letter",
"Understanding the C language"
};
printf("你好阿,我是电脑机器人,我有一些智慧\n");
printf("他们是什么呢?哦,对了,这里有部分清单:");
for(i = ; i < LIM ; i++){
puts(mytal[i]);
}
puts(m3);
gets(name);
printf("哦,%s,%s\n",name,MSG);
printf("%s\n%s",m1,m2);
gets(talents);
puts("Let's see if I've got that list: ");
puts(talents);
printf("谢谢你的信息,%s\n",name);
return ;
}

  2.定义字符串:基本的方法有字符串常量,char数组,char指针和字符串数组。

    1)字符串常量:属于静态存储,是指如果在一个函数中使用字符串常量,即使多次调用这个函数,这个字符串在程序的整个运行过程中只存储一份。整个引号的内容作为指向该字符串存储位置的指针。

    例如:

#include<stdio.h>
int main(){
printf("%s,%p,%c\n","We","are",*"World");
}

  显示结果为:We 0x2321342 W

    2)字符串数组及其初始化

     第一种方法是定义数组的大小,然后给出字符串。

     第二种方法是不给出数组的大小,然后给出字符串,大小由编译器计算。

     第三种方法是如果定义的数组需要在程序运行时才放入字符,那么必须要指明数组的大小。

     第四种方法任何数组名都是数组首元素的地址。m1 == &m1[0]

     第五种方法是用指针符号来建立字符串:例如 const char *m3 = "Hello"   它和char m3[] = "Hello" 作用几乎相同。

     3. 但是也存在区别:数组初始化是从静态存储区把一个字符串复制给数组,而指针初始化只是复制字符串的地址。

#include<stdio.h>
int main(){
char heart[] = "I love Tillie!";
char *head = "I love Millie!";
int i ;
for(i = ; i < ; i++){
putchar(heart[i]);
}
printf("\n");
for( i = ; i < ; i++){
putchar(head[i]);
}
}

    4.在这个程序中,我们学到的知识: 1)*head =head[0] 2)如果head = heart。那么head就指向了heart字符串,那么原来的Millie还是存在的,但是如果没有保存这个字符串的地址的话,就没有办法再访问这个字符串了,石沉大海了。很难遇到。

    这里需要引入一个问题,char *word = "frame" , word[1] = 'l' => 这样做允许吗?  解答:可能编译器允许这么做,但是会造成内存访问错误。如果编译器使用这种单个拷贝表示法允许把第一个字符改变,那将影响到所有对这个字符串的使用,建议的做法是初始化一个指向字符串文字的指针使用const修饰符, const char *p1 = "Klingon" ;

    5.字符串数组:像最上面的程序中定义了一个指针字符数组。

    这样的一个字符数组在解释上类似于一个二维数组。

    区别是前一个是存放地址的数组,后者是放着完整的字符数组。

    最后要建立一种认识,绝大多数字符串使用的都是指针。观察这个程序

#include<stdio.h>
int main(){
char *mesg = "Don't be a fool!";
char *copy;
copy = mesg;
printf("%s",copy);
printf("mesg = %s,&mesg = %p;value = %p\n",mesg,&mesg,mesg);
printf("copy = %s,&copy = %p;value = %p\n",copy,&copy,copy

  这个运行结果表明:两个指针变量指向的都是同一个字符串。

11-2:字符串的输入: gets()函数 scanf() 函数  fgets()函数

  注意:在输入字符串的时候,要提前申明一块足够大的区域给它,计算机是不会计算字符串的长度的,后果是会导致输入的字符覆盖程序中其他的数据和代码,导致程序异常终止。

  1.gets()函数:从系统的标准输入设备获得一个字符串,当读到\n的时候,停止输入,舍去\n,补充\0。gets()函数如果成功读取字符串,会返回这个字符串的地址,例如char *ptr , ptr = gets(name);如果出错或者遇到文件结尾,它返回一个空(或0)地址。称为空指针。在<stdio.h>中用NULL来表示。gets(name)!=NULL

  2.fgets()函数:fgets()函数要求指定最大的字符数,fgets(name,MAX,stdin) ,如果遇到换行符,也会把它读取,而不会扔掉。如果成功读取了字符串,会返回这个字符串的地址。如果出错或者遇到文件结尾,它会返回一个空(或0)地址。

  3.scanf()函数:比较的约束,%s,遇到空白符(空格,制表符,换行符)等都会停止。如果%10s,那么函数就会读取10个或以下停止。如果成功读取了字符,它会返回读取字符的个数,否则返回EOF。

  最后总结:gets()函数读取文本更快更好,scanf()函数主要以某种标准输入的混合类型数据的读取和转换。

            

  

《C prime plus (第五版)》 ---第11章 字符串和字符串函数的更多相关文章

  1. C primer plus 第五版十二章习题

    看完C prime plus(第五版)第十二章,随带完成了后面的习题. 1.不使用全局变量,重写程序清单12.4的程序. 先贴出12.4的程序,方便对照: /* global.c --- 使用外部变量 ...

  2. 《C prime plus (第五版)》 ---第11章 字符串和字符串函数---3

    字符串函数总结: 下面是头文件 string.h 中定义的函数: 序号 函数 & 描述 1 void *memchr(const void *str, int c, size_t n)在参数  ...

  3. 《C prime plus (第五版)》 ---第11章 字符串和字符串函数---4

    字符串的例子: 1.字符串排序: 应用范围:准备花名册,建立索引以及很多情况下都会用刀字符串的排序.这个程序的主要工具就是strcmp(). 算法:读一个字符串数组,对它们进行排序并输出. #incl ...

  4. 《C prime plus (第五版)》 ---第11章 字符串和字符串函数---2

    11-3:字符串 输出 三个标准的函数:puts() fputs() printf() 1.puts()函数: #include<stdio.h> #define DEF "I ...

  5. 《C prime plus (第五版)》 ---第12章 存储类.链接和内存管理

    12-1:存储类: 1.作用域: 代码块作用域,函数原型作用域和文件作用域. 2.链接:分为外部链接,内部链接和空链接.代码块作用域和函数原型作用域都是空连接,意味着是私有的.而文件作用域的变量可能是 ...

  6. 数据通讯与网络 第五版第24章 传输层协议-TCP协议部分要点

    上一博客记录了UDP协议的关键要点,这部分记录TCP协议的关键要点. 24.3 传输控制协议(TRANSMISSION CONTROL PROTOCOL) TCP(Transmission Contr ...

  7. 数据通讯与网络 第五版第24章 传输层协议-UDP协议部分要点

    24.1 介绍 本章节主要集中于传输层协议的解读,图24.1展示TCP.UDP.SCTP在TCP\IP协议栈的位置 24.1.1 服务(Service) 每个协议都提供不同的服务,所以应该合理正确的使 ...

  8. 《Python学习手册 第五版》 -第11章 赋值、表达式和打印

    上一章对Python的语句和语法已经进行了基本的说明,接下来就是每个章节的详细说明,本章的主要内容就是标题中涵盖的三点:赋值语句.表达式语句.打印语句 本章重点内容如下: 1.赋值语句 1)赋值语句的 ...

  9. 《Python学习手册 第五版》 -第13章 while循环和for循环

    上一章已经讲过if条件语句,这章重点是循环语句:while.for 本章的重点内容 1.while循环 1)一般形式 2)break.continue.pass和循环的else 2.for循环 1)一 ...

随机推荐

  1. (原创)lightgbm 一些错误情况处理

    1.做多分类问题时候(mutticlass),如果遇到 lightgbm.basic.LightGBMError: b'Number of classes should be specified an ...

  2. [Python] SQLBuilder 演示样例代码

    用Python写一个SQLBuilder.Java版能够从 http://www.java2s.com/Code/Java/Database-SQL-JDBC/SQLBuilder.htm 看到. 附 ...

  3. 负载均衡情况下获取真实ip的方法

    公司用了硬件负载均衡,最近发现日志中的用户ip都为负载均衡器的ip,业务需要所以要改为用户真实ip,下面记录一下! 1.打开文件:/etc/httpd/conf/httd.conf. 2.在文件中查找 ...

  4. hdu3076--ssworld VS DDD(概率dp第三弹,求概率)

    ssworld VS DDD Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  5. WPF自定义依赖集合属性无法触发更新的问题

    通常WPF中通过继承UserControl的来快速创建自定义控件,最近项目上需要设计一个卫星星图显示控件,最终效果如下图所示.完成过程中遇到了自定义集合依赖属性无法触发更新通知的问题,在此记录一下,方 ...

  6. Flume-1-7-0用户手册

    介绍 概述 Apache Flume是为有效收集聚合和移动大量来自不同源到中心数据存储而设计的可分布,可靠的,可用的系统. Apache Flume的用途不仅限于日志数据聚合.由于数据源是可定制的,F ...

  7. Hibernate学习六----------CRUD

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

  8. CXF webservice 一个简单的demo

    新建一个maven项目(or下载cxf所需jar包),pom.xml如下 1.pom.xml <project xmlns="http://maven.apache.org/POM/4 ...

  9. 使用python处理实验数据-yechen_pro_20171231

    整体思路 1.观察文档结构: - 工况之一 - 流量一28 - 测点位置=0 -测点纵断面深度-1 -该点数据Speedxxxxxxxx.txt -测点纵断面深度-2 -测点纵断面深度-3 -... ...

  10. spring源码解析之IOC容器(一)

    学习优秀框架的源码,是提升个人技术水平必不可少的一个环节.如果只是停留在知道怎么用,但是不懂其中的来龙去脉,在技术的道路上注定走不长远.最近,学习了一段时间的spring源码,现在整理出来,以便日后温 ...