字符串: C语言中最有用、最重要的数据类型之一。

字符串:是以\0字符结尾的char类型数组。所以可以把数组和指针知识应用于字符串。

如何在程序定义字符串:

1、字符串字面量

用双引号括起来的内容称为字符串字面量,也叫作字符串常量。双引号中的字符和编译器自动加入末尾的\0字符,都作为字符串储存在内存中。

如果要在字符串内部使用引号,必须要在双引号前面加上一个反斜杠(\)

字符串字面量被视为const,就不能更改了。

字符串常量属于静态存储类别。这说明如果在函数中使用字符串常量,该字符串只会被储存一次,在整个程序的生命期内存在,即使函数被调用多次。用双引号括起来的内容被视为指向该字符串储存位置的指针。

2、字符串数组和初始化

定义字符串数组时,必须让编译器知道需要多少空间,一种方法是足够空间的数组储存字符串。

指定数组大小的时候,必须确保数组的元素个数至少比字符串长度多1;

省略数组初始化声明中的大小,编译器会自动计算数组的大小;

数组表示法_创建字符串:char words[MAXLENGTH]=“I am a string in an array.”

指针表示法_创建字符串:char * pt1 = “Something is pointing at me.”

3、数组和指针

数组表示法_创建字符串:char words[MAXLENGTH]=“I am a string in an array.”

这种表示法,字符串字面量被存储在静态存储区。数组只有在运行时才会被分配内存。此时,才将字符串拷贝到数组中。此时字符串有两个副本,一个是在静态内存中的字符串字母量,另一个是储存在words数组中的字符串。

指针表示法_创建字符串:char * pt1 = “Something is pointing at me.”

编译器为字符串在静态存储区预留了29个元素的空间。一旦开始运行程序,它就会为指针变量pt1留出一个储存位置,并把字符串的地址储存在指针变量中。

4、数组和指针的区别

char heart[] = “I love Tillie!”;  ->数组名heart是常量;

const char *head = “I love Millie!”; ->指针名是head变量;

head =heart ->可以;

heart =head –>不可以,非法构造,赋值运算符左边必须是变量;

5、字符串数组

const char *mytalents[LIM]={

"Adding number swiftly",

"Multiplying accurately",

"Stashing data",

"Following instructions to the letter",

"Understanding the C language"

};

char yourtalents[LIM][SLEN]={

"Walking in a straight line",

"Sleeping","Watching television",

"Mailing letters","Reading email"

};

字符串数组分配内存的使用率低。因为数组中储存着字符串字面量的副本。每个字符串都被储存了两次。

如果要使用数组表示待显示的字符串,建议使用指针数组。指针数组也有缺陷,就是字符串字面量不能更改。如果要改变或者为字符串输入预留空间,不要使用指向字符串字面量的指针。

++++++++++++++++++++++++++++++++++++++++++++++++++++++

字符串的输入:

想把字符串读入程序,首先必须预留储存该字符串的空间。然后用输入函数获取该字符串。

如何分配空间:

  要做的第1件事就是分配空间。以储存稍后读入的字符串。意味着必须为字符串分配足够的空间。不能指望计算机在读取字符串时顺便计算它的长度。

char *name;

scanf(“%s”,name);

name是未初始化的指针,name可能指向任何地方。所以可能会擦写掉程序中的数据或代码,从而导致程序异常中止。

最简单的办法:在声明时显式指明数组的大小。

char name[81];

现在name是一个已分配块(81字节)的地址。还有一种办法就是使用C库函数来分配内存。

  空字符:

用于标记C字符串末尾的字符;对应的字符ASCII编码是0;

  空指针:

有一个值,该值不会与任何有效的地址对应。

  本质上讲空字符是整数类型,占1个字节;

  空指针是指针类型,是一个地址,占4个字节。

  丢弃输入行中余下的字符,是因为,输入行中多出来的字符会被留在缓冲区中。成为下一次读取语句的输入。

  

  1、gets() 函数    这个函数不安全,被摒弃了

  scanf()和转换说明%s只能读取一个单词,可是在程序中经常要读取一整行输入,而不仅仅是一个单词。

很久前gets()就用于处理这种情况。gets()函数简单易用,它读取整行输入,直至遇到换行符。

gets()函数有个问题,无法检查数组是否装得下行。数组名会被转换成数组首元素的地址。get()函数只知道数组的开始处,并不知道数组中有多少个元素。

如果输入字符串过长,会导致缓冲区溢出(buffer overflow)。多余的字符超出了指定的目标空间。如果这些多余的字符只是占用了尚未使用的内存,就不会立即出现问题。但是一旦擦写掉程序中的其他数据,就会导致程序异常中止。

C99标准建议不要使用get()函数,甚至被C11标准摒弃了。

  

  2、fgets()函数

  函数原型:char *fgets(char *buf, int bufsize, FILE *stream);  ---->从指定的文件读取一个字符串

buf 字符型指针,指向存储读入数据的缓冲区的地址;---->存到哪

n 从流中读入n-1个字符;--->读多少个

stream 指向读取的流;   --->从哪读

会在读入的最后一个字符后加上串结束标志'\0'

返回值:读取失败或读到文件结尾返回NULL;输入成功时,返回 char 型指针,指向读入的字符串内容,含换行键;

  为什么会有换行符问题:因为输入时会敲回车嘛,就产生换行符。函数会把换行符一并存储起来。(读一行字符串的范畴)

  fgets()会存储换行符,有好处也有坏处。好处就是:检查末尾有没有换行符就知道是否读取了一整行。坏处就是:你可能并不想把换行符储存在字符串中,这样的换行符会带来一些麻烦。

  如何处理掉换行符:在已经储存的字符串中查找换行符,将其替换成空字符

while (words[i] != ‘\n’)

i++;

words[i]=’\0’;

  

  3、gets_s()函数

  函数原型: gets_s(words,STLEN);

只从标准输入中读取数据,不需要第3个参数;

如果读到换行符,会丢弃它,而不是储存它;(不存换行符)

如果读到最大STLEN字符数的话,.....很复杂;

没有fgets()函数灵活,易用;不建议用;

  4、s_gets()函数

函数实现如下:

 char * s_gets(char * st, int n)
{
char * ret_val;
int i=; ret_val = fgets(st, n, stdin); //读取成功,返回一个指针,指向输入字符串的首字符;
if(ret_val)
{
while(st[i]!='\n' && st[i]!='\0')
i++;
if(st[i] =='\n') //fgets会把换行符也吃进来了,fgets会在末尾自动加上\0;
st[i]='\0';
else //其实是'\0'
while(getchar() != '\n') //会把缓冲区后续的字符都清空
continue;
}
return ret_val;
}

特性:1、会吃进换行符,但是会将其替换成\0空字符;2、会把\0后续的缓冲区内容都清空,为的是不干扰下次输入;

  5、scanf()函数

  函数原型:int scanf(const char * restrict format,...);

  返回一个整数值:该值等于sanf()成功读取的项数或EOF(文件结尾)。文件结尾不存在于文件中,而仅仅是一种标志,流的状态的标志。

scanf("%d %d",&a,&b);
函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2;
如果只有a被成功读入,返回值为1;
如果a和b都未被成功读入,返回值为0;
如果遇到错误或遇到end of file,返回值为EOF。end of file为Ctrl+z 或者Ctrl+d。

++++++++++++++++++++++++++++++++++++++++++++++++++++++

字符串的输出:

1、puts()函数

自动在字符串末尾加上换行符,\n

函数只用来输出字符串,没有格式控制,里面的参数可以直接是字符串或者是存放字符串的字符数组名。

2、fputs()函数

int fputs(const char *str, FILE *stream); ---->向指定的文件写入一个字符串;

str  这是一个数组;

stream 指向FILE对象的指针,该FILE对象标识了要被写入字符串的流。

3、printf()函数

函数的输出格式很多,可以根据不同格式加转义字符,达到格式化输出。

C语言风格字符串的概念、定义、输入字符串、输出字符串的更多相关文章

  1. 面试题之java 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 要求不能出现截半的情况

    题目:10. 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串. 但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输 ...

  2. 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”。

    一.需要分析 1.输入为一个字符串和字节数,输出为按字节截取的字符串--->按照字节[byte]截取操作字符串,先将String转换成byte类型 2.汉字不可以截半--->汉字截半的话对 ...

  3. java算法面试题:编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个, 如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉的半个”。

    package com.swift; import java.util.Scanner; public class Hanzi_jiequ { public static void main(Stri ...

  4. 4.写一个控制台应用程序,接收一个长度大于3的字符串,完成下列功能: 1)输出字符串的长度。 2)输出字符串中第一个出现字母a的位置。 3)在字符串的第3个字符后面插入子串“hello”,输出新字符串。 4)将字符串“hello”替换为“me”,输出新字符串。 5)以字符“m”为分隔符,将字符串分离,并输出分离后的字符串。 */

    namespace test4 {/* 4.写一个控制台应用程序,接收一个长度大于3的字符串,完成下列功能: 1)输出字符串的长度. 2)输出字符串中第一个出现字母a的位置. 3)在字符串的第3个字符 ...

  5. QuickHit项目(输出字符串游戏)

    public class leve { private int leveNo; private int strLength; private int strTimes; private int tim ...

  6. C++_系列自学课程_第_9_课_C语言风格字符串_《C++ Primer 第四版》

    前面说了写关于数组和指针的内容,这次在这里讨论一下字符串,讨论一下C语言风格的字符串. 在C语言里面我们利用字符数组来对字符串进行处理, 在C++里面我们前面说过一种类类型string可以对字符串进行 ...

  7. C++的string类型和继承C语言风格的字符串的区别与注意事项

    1.尽可能地在C++程序中使用string,不要使用继承而来的C语言风格的字符串,会出现许多安全问题. 2.C语言的字符串风格,是以空字符结束的,在C++的头文件cstring中定义了C语言风格的字符 ...

  8. c语言学习笔记第四章——字符串和格式化输入、输出

    B站有视频演示 本章学习printf函数的输入输出,字符串的定义与实用. 字符串 字符串(character string)是一个或多个字符的序列,如下所示: "Zing went the ...

  9. 【1024打卡】C++字符串的输出((c语言风格)

    c++字符串输出(c语言风格) 文章目录 c++字符串输出(c语言风格) 杂记 代码 杂记 今天程序设计竞赛白给了,果然还是太弱了,y总带带我TAT ┭┮﹏┭┮1024快乐 代码 c语言学习 #inc ...

随机推荐

  1. Python 学习之---文件目录处理

    前言:有关文件夹与文件的查找,删除等功能 在 os 模块中实现.使用时需先导入这个模块, 导入的方法是:import os   一.取得当前目录 s = os.getcwd() s 中保存的是当前目录 ...

  2. linux命令-mount挂载umount卸载

    格式化完成之后想写数据 要先挂载 //////////////////////////////////////////////////////////////////// [root@wangshao ...

  3. 用JS,打印99乘法表

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  4. Hbase批量插入优化记录

    2016年5月11日10:08:29 hbase原本的put方式是一条一条的put,在客户端修改 AutoFlush 将HTable的setAutoFlush设为false,可以支持客户端批量更新.即 ...

  5. spring整合web项目演示

  6. group()、start()、end()、span()

  7. 企业级搜索引擎Solr 第三章 索引数据(Indexing Data)

    虽然本书中假设你要建索引的内容都是有着良好结构的,比如数据库表,XML文件,CSV,但在现实中我们要保存很混乱的数据,或是二进制文件,如PDF,Microsoft Office,甚至是图片和音乐文件. ...

  8. PLSQL语法

    Procedural Language和SQL的结合体.通过增加变量.控制语句,使我们可以写些逻辑更加复杂的数据库操作 语句框架组成 declare – 可选 声明各种变量或游标的地方. begin ...

  9. 进度条控件JProgressBar的使用

    ----------------siwuxie095                             工程名:TestUI 包名:com.siwuxie095.ui 类名:TestList.j ...

  10. iOS 列表三级展开

    效果图如下:        #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDe ...