字符和字符串输入输出

一、字符串的输入

1scanf

输入:

char name[81];

scanf(“%s”,name);

注意不能用

char *name;

scanf(“%s”,name);

因为这样声明的话,不知道name的值,即不知道name到底指向那块内存。

 

scanf输入时,会跳过前面所有空白字符,直到再次遇到空白字符才会结束输入,并在读入的字符串后面自动加一个’\0’。同时会将后面的空白字符留在输入流中。

 

2gets

char name[81];

    gets(name);或者

   char *ps

   ps= gets(name)

Ø         gets()函数以换行符作为结束的标记;

Ø         它会将换行符前面的所有字符读入,并在字符串后面自动加一个’\0’

Ø         换行符将被丢弃,换行符后面的仍留在输入流。

Ø         gets()函数就是可以无限制地读入,多出来的字符会溢出到相邻的内存。

Ø         gets()在现在机器上,如果输入ctrl+Z会返回NULL,但注意,此时name没读到值,但其地址不变,也就是说,gets()的返回值不是赋给name的。

Ø         gets函数的参数必须是一个已分配内存的地址。

Ø         返回一个char型指针,指向字符串(首字符)地址,如果输入ctrl+Z,返回值是一个NULL,但name仍是原来的地址。

说明:namegets的参数,所以必须是已分配内存的。而一个数组一旦声明了,系统会自动分配内存,因此可以做参数。但ps就不行,因为ps没有初始化,不知道它指向哪块内存。

ps可以用来接受getsname)的返回值,如果读入成功,就返回字符串地址,这时ps就是name的地址。如果读入不成功,name还是原先地址,但ps变成了NULL

关于gets,请参看示例一、二。

 

 

3fgets()

需要制定最大字符读入数,是为文件I/O设计的,处理键盘输入时不如gets()方便。

Ø         它需要第二个参数来制定最大读入字符数。如果读入字符数达到这个值,或者遇到一个换行度,就停止读入;

Ø         如果遇到换行符,该换行符将被读入字符串,再在换行符后加一’\0’

Ø         还需要第三个参数指定读哪个文件。如果是从键盘上读入数据,就用stdin

Ø         该函数返回一个char型指针,指向字符串(首字符)地址

例子:

1)标准输入

char name[80];

    char *ptr;

    ptr=fgets(name,81,fp);

    printf("name: %s,  ptr: %s\n",name,ptr);

2)从文件读入

FILE *fp=fopen("E:\\code\\wordcopys.txt","r");

    char name[80];

    char *ptr;

    ptr=fgets(name,81,fp);

    printf("name: %s,  ptr: %s\n",name,ptr);

这里要特别注意的是,"E:\\code\\wordcopys.txt"一定要用\\,不能用一个\.

另外,要注意的是,name字符串除了’\0’,最后一个字符是换行符。

如果wordcopys.txt和程序在同一个目录下,也可直接写为

FILE *fp=fopen("wordcopys.txt","r");

还有一点要注意的是:scanf会忽略前面所有的空白字符,但getsfgets不会。

 

二、字符串的输出

1printf (“%s”,name);

name是字符串的地址。

 

2puts()

给出字符串的地址即可,与printf不同的是,这个函数会在字符串后面自动添加换行符。

注意,我们并不一定要给一个字符串的首地址,只要是一个char型地址就行,函数会从这个地址的字符开始输出,直到遇到空字符’\0’

 

3fputs

puts的面向文件版本,两者之间的主要差别是:

Ø         fputs需要第二个参数来说明要写的文件,如果输出到屏幕上,就用参数stdout

Ø         fputs不会自动添加换行符。

 

注意,gets()会丢掉换行符,但puts()会自动添加换行符;

fgets()会加上换行符,但fputs()不会添加换行符。

所以,如果将fgets()puts()一起使用,将会输出两个换行符;

如果将gets()fputs()一起使用,将不会输出后将不会换行(一个换行符也没有)。

 

printf也不会自动添加换行符,且要键入更多代码,但是这个函数使得在一行上输入多个字符串更为简便。

 

最后,我们可以根据需要,用上述函数建立适合自己的输入、输出函数

 

 

示例1gets()函数1

char *str1;

if(gets(str1)==NULL)

    printf("Nothing!");

如果我们输入ctrl+Z,没有问题,会输出Nothing!

但是当我们输入其它任何字符(包括直接回车),都会提示出错。原因是,str1是一个没有初始化也没有赋值的指针,所以不能给他输入任何字符。

这里大家可能要问,“gets()函数以换行符作为结束的标记”,也就是说,我既然直接输入换行符,那不就是什么也没输入,为什么也不可以呢?注意,这时,系统会认为你输得是一个空字符串,因此,会自动给你加一个’\0’。也就说,我们等于是在一个未赋值的指针中存了一个空字符。

那么,为什么输入ctrl+Z可以呢?因为ctrl+Z是真正告诉系统我什么都没输入,包括空字符串,因此,不会放任何东西在那里。

 

示例2gets()函数2

char str1[NUM];

gets(str1);

if(str1==NULL)

    printf("Nothing!");

我们不管输入什么,即使是ctrl+Z,也不会打印任何东西出来,也就是说,str1都不是NULL

说明:

str1是数组名,而这个数组名和指针变量不同的是,他在声明时,系统会自动为其分配内存,不管我们输入什么,这个地址都是实实在在分配好了的,所以永远不会为NULL。当我们输入ctrl+Z时,只是告诉系统我没有向这个内存放任何东西,事实上,这个内存有可能有一些数据,是原先就有的、没有清楚的垃圾。当然,即使这块内存是空的也无所谓,我们这个NULL不是说你这里存没存东西,而是看你到底有没有指定内存。

事实上,这时gets函数会返回一个NULL,但返回值并不是赋给str1的。

 

 

示例3

char *str1;

if(str1==NULL)

    printf("Nothing!");

大家可能以为这时会打印Nothing!,事实上也不会打印,为什么呢?因为系统会随机给它一个分配内存,就好像其它变量一个,给一个随机值,所以str1不是NULL。大家可能又会问,既然有内存,那我在示例1中为什么不能用gets函数呢?因为这个内存是随机指定的,此时这个内存实际上并未给str1使用,也就是说,系统还未授权,所以,不能赋值。

如果我们将上述事例改成:

char *str1=NULL;

if(str1==NULL)

    printf("Nothing!");

这时,就会打印Nothing!

通过用NULL显示初始化str1,就是告诉系统不要将它和任何内存地址联系在一起。

其实这也就可以看到,我们用指针时,最好初始化,如果暂时还不知道要分配的内存,那也最好用NULL显示初始化。因为如果让系统随机指定一个内存,在某些情况下,我们可能可以使用这块内存,而这块内存可能存的是一些重要数据。因此,对指针变量最好是进行初始化才比较安全。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值