表示字符串和字符串I/O

1.gets()函数与puts():

        相比于scanf()函数的一次只能读取一个单词,gets()可以在程序中进行一整行的输入,其经常和puts()配对使用,使用时方法如下:

#include<stdio.h>
#define a 40
int main(){
char word[a];
puts("bearst wu");
gets(word,a,word);
printf("%s\n",word);
puts(word);
return 0;
}

 其中的puts()会放入word[]数组中,在最后可以直接使用printf()进行输出,也可以使用puts()进行输出

printf("%s",word);
puts(word);

 但gets()  还是存在安全方面的漏洞,gets()只能知道数组的开始的地方,并不能知道数组中一共有多少元素,那么很容易导致缓冲区溢出,个人理解是有可能会造成访问未被分配的空间

虽然gets()存在不少的问题,但作为函数而言,只要使用得当的确很方便(反正我是拒绝不了这种方便)不过在c11标准中其被废除,所以在使用部分编辑器时,应当注意编辑器对gets() 是否支持。

gets_s() 

 当然随着gets()函数的消失,必须要有一种新的函数可以取代gets() 函数,而做到这个作用的便是gets_s() 函数(感觉还不如对 gets()进行更改,让它可以适配各种情况多好...)。

当然这次的改变的确有部分的变化

1.gets_s()面对一个换行符时会将其丢掉而不是和fgets()一样的保存(那就是说,输入不超出就差不多咯?)

2.如果fgets_s()在允许的最大的字符串之前都没有读取到换行符,然后丢掉里面的输入,一直到换行符或者文件最后(不是特别理解的行为)然后可能会中止或者退出函数。

 fets()与fputs()

fets()是通过第二个参数限制读入的字符串来解决溢出不安全的问题

第二个参数是指明了读入字符的最大数量,如果是n,那么只能到达n-1个地方或者在换行符时结束。

第三个参数是读入的文件,如果是从键盘里面输入的数据,这里可以使用stdin作为参数,当然,目前所说到的都是在stdio.h中

而作为和fgets()配对的fputs()来说相应的也需要一个标准输出的stdout作为参数

举个例子

#define a 40
#include<stdio.h>
int main(){
char word[a];
puts("hello world");
while(fgets(word,a,stdin)!=NULL&&word(0)!='\n')
fputs(word,stdout);
puts("Done.")
return 0;
}

这个中间即使是允许读入的字符再小,也可以将其全部输出,这个主要原因是是其中的\0起到的作用和\n(我也没有想到会是这个样子说实话)

当然,也可以有其他的办法来把这些\n去掉

while(getchar()!='\n')
continue;

字符串函数

strlen() 使用string.h

strlen()函数是进行统计字符串长度的函数其会统计正在输入的字符串中的元素(但并不包括\0)而在sizeof()函数中会统计到\0

当然,strlen()的作用并不是只有这么一点,发挥想象的话,它的确可以完成不少的事情

#include<stdio.h>
#include<string.h>
void a(char *string,unsign int size){
if(strlen(string)>size)
string[size]='\0'
}

比如说这个函数,可以缩短字符串的长度。

特别需要注意的是,因为是要继续修改里面的值,所以不可以使用const的限定符

#include<stdio.h>
#include<string.h>
void a(char *string,unsign int size){
if(strlen(string)>size)
string[size]='\0'
}
int main()
{
char me[]="bearst  wuqh"
puts(me);
a(me,11);
puts(me);
puts(me+12);
}

 在这个表达式中,me+12代表的是me[12]的地址,这里按照道理来说应该是空格字符,所以这里普通()显示的是一直到这个空格之前的所有字符,这么来说,假如这里是me+7的话,是不是可以输出bearst呢..好像很有道理的样子

strcat() string.h

和strncat()函数相似,都是接受两个字符串作为参数,同时把第二份的字符串附加到第一个字符串的后面,形成新的字符串,但第二个字符串并不会发生改变 

举个例子

#include<stdio.h>
#include<string.h>
#define si 40

char * s_gets(char *st,int i){
char * ret;
int n=0;
ret=fgets(st,i,stdin);
if(ret){
while(st[i]!='\n'&&st[i]!='\0')
i++;
if(st[i]=='\n')
st[i]='\0';
else
while(getchar()!='\n')
continue;
}
return ret;
}


int main()
{
char flower[si];
char addon[]="s small like ";
if(s_gets(flower,si)){
strcat(flower,addon);
puts(flower);
puts(addon);
}
return 0;
}

在这个函数使用的过程中 

在输入完一串字符串之后,其flower会发生改变,但输出addon并没有发生什么改变

strcmp()

 这个函数的最主要的作用是把要反映的和客户输入的部分进行比较

比如说,我要对 a和b进行比较便可以得到他的返回值-1,原因是a 是b -1单位处的元素,那么我想可以根据这个特点进行定点的删除或者判断是不是处于同一个位置,可以说这后面的才是他的主要用途

举个例子

if(strcmp(word,"quit")==0)
puts("bye");

 

if(ch=='q')
puts("bye");

 

而strncmp函数和这个不同的是他会一直比较到出现第三个参数要求的地方



#include <stdio.hs
#include<string.h>
define LISTSIZE 6
int main()
const char *list[LISTSIZE] ={
"astronomy","astounding",
"astrophysics","ostracize",
"asterism""astrophobia"
};
int count =0;
int i;
for (i=0;i<LISTSIZE; i++)
if (strncmp(list[i],"astro", 5)== 0)
printf("Found: ₴s\n", list[i]);
count++;
printf("The list contained d words beginning"" with astro.\n", count);
return 0;

像这个程序来说,会对里面的单词进行比较,一直到符合’astro‘这五个字母的部分所出现,同时我认为也保留了strcmp函数的大部分的功能(主要原因是我也不太清楚那里没有保留..)

strcpy()

 我们之前学习过对单个字符的赋值运算符,但面对字符串,我们一般只能使用char类型来定义一个一个数组,然后根据这个数组来进行赋值一类的运算,,那么我们可不可以puts()一段字符串之后然后直接拷贝到数组之中呢,这里需要使用到strcpy函数,


char* s_gets(char * st, int n);
int main(void)
char qwords [LIM] [SIZE];
char temp [SIZE];
int i = 0;
printf("Enter &d words beginning with q:\n", LIM); while (i< LIM && s gets(temp, SIZE))
if(temp [0] !='q')
printf("&s doesn't begin with g!\n", temp); else
strcpy(qwords[i], temp) ;
i++;
puts("Here are the words accepted:");
for (i=0;i< LIM;i++)
puts(qwords[i]);
return 0;

 这样子可以先判断第一个字母是不是p,然后再对里面的字符串复制到qword()数组中。

当然他也不是不可以复制部分,比如说,


puts(copy);
ps = strcpy(copy + 7, orig); puts(copy);
puts(ps);
return 0;

 值得注意的是,在复制的过程中空格也算是一个字符,所以说,在复制时要考虑清楚空格的存在

但他也存在内存可能溢出的问题,所以可以使用更加谨慎的函数strncpy(),这种情况下,如果输入太大而可能造成溢出时,会对其中的空字符进行删除的处理,来确保可以保存其中有用的目的但如果实在是装不下的话,他可能会将最后一个放为空字符

sprintf()

这个函数和printf()很类似,但也有其中不一样的地方,比如说,他会将你输入的数据存到字符当中

但printf()会将你输入的放到显示屏上,


#include <stdio.h>
#define MAX 20
char *s_gets(char *st, int n);
int main(void)
charfirst[MAX];
char last [MAX]i
char formal[2 * MAX + 10];
double prize;
puts("Enter your first name:");
s_gets(first, MAX);
puts("Enter your last name:");
s_gets(last, MAX);
puts("Enter your prize money:");
scanf("%lf",&prize);
sprintf(formal, "&s, %-19s: $%6.2f\n", last, first, prize);
 puts(formal);
return 0;
)

sprintf(formal, "&s, %-19s: $%6.2f\n", last, first, prize);

在这一行会将你输入的三个数据进行整合,最后可以对其进行输出,当然在这个函数中间的确看不出来有什么简单的地方,但也许在后面的学习里面有更多的作用吧

                                                                              2020-11-18    13-53

                                                                                                bearst

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值