字符串操作系列库函数

scanf()函数  要注意的点:

#include <stdio.h>

int main()
{
    char a[100]={1,2,3,4,5,6,7,8,9,10};
    scanf("%s",a);
    int i;
    for (i = 0; i<10 ; i++)
    {
        printf("%d\n",a[i]);
    }
        
    return 0;
}

scanf()对回车符认为是结束符,结束略过。对于空格也认为是输入结束。

输入:aa 回车

aa
97  //a
97  //a
0    //结束
4
5
6
7
8
9
10

输入:aa 空格 bb 

aa bb
97  //aa
97  //aa
0  //结束
4  //没有b,被舍弃
5  //没有b,被舍弃
6
7
8
9
10

 

通过scanf输入的时候,最后按的是一个什么键?回车键,回车键scanf会认为是输入完成,而不是字符串的内容
scanf认为回车和空格都代表输入完成
当字符数组的成员数量小于用户在键盘输入字符的数量之后,scanf并不会自动处理,而是把用户输入的所有字符都放入了数组,导致数组溢出了

gets()函数

示例:

 #include <stdio.h>
 
 int main()
 {
        char c[100] = {0};
         gets(c);
        printf("%s\n",c);
    return 0;
 }

 

对比scanf(),这里输入空格,gets()能传输空格,接收一行,输出一行。

abc@ubuntu:~$ gets
Hello World!
Hello World!

gets()和scanf()函数的区别

scanf( )函数和gets( )函数都可用于输入字符串,但在功能上有区别。若想从键盘上输入字符串"hi hello",则应该使用"gets()"函数。

gets可以接收空格;而scanf遇到空格、回车和Tab键都会认为输入结束,所有它不能接收空格。

char string[15]; gets(string); /*遇到回车认为输入结束*/

scanf("%s",string); /*遇到空格认为输入结束*/

所以在输入的字符串中包含空格时,应该使用gets输入。

gets认为回车代表输入完成,空格只是字符串中的一部分而已
gets和scanf一样有缓冲区溢出的危险

fgets()函数 

#include <stdio.h>

int main()
{
        char a[10]={0};
        fgets(a,sizeof(a),stdin);
        printf("%s",a);
        return 0;
}

fgets()没有了scanf()与gets()缓冲区溢出的问题。fgets()是一个安全的函数,中间有限定接收的长度,超出长度无效。fgets会认为用户输入的回车也是字符串的一部分内容,fgets是安全的,不会因为用户恶意的输入过长的字符串导致溢出。

 

puts()函数

#include<stdio.h>

int main()
{
        char a[]="Hello World!";
        puts(a);//自动加一个\n
        return 0;
}

运行:

abc@ubuntu:~$ puts
Hello World!
abc@ubuntu:~$    //已经换行了

自动加一个\n,换行。看示例:

#include<stdio.h>

int main()
{
        char a[]="Hello World!\n";//手动加一个换行符
        puts(a);
        return 0;
}

结果:

abc@ubuntu:~$ gcc -o puts puts.c
abc@ubuntu:~$ puts
Hello World!      //两个换行

abc@ubuntu:~$ vi puts.c

手动加了个\n输出时打印了2个换行。说明puts()会自动加上一个换行。printf()不会自动加换行。

fputs()函数

比puts()多了一个参数:stdout;  fputs()函数不会自动加换行。

#include<stdio.h>

int main()
{
        char a[]="Hello World!";
        //puts(a);
        fputs(a,stdout);
        return 0;
}

不会自动加上换行:

abc@ubuntu:~$ gcc -o fputs fputs.c
abc@ubuntu:~$ fputs
Hello World!abc@ubuntu:~$ vi fputs.c   //没有换行


fputs并不会像puts那样输出的时候自动结尾加\n

 

strlen()函数 字符串长度

要包含头文件 <string.h>

我们自己可以实现:求字符串的长度。

#include <stdio.h>

int main()
{
        char a[100]= "hello world!";
        unsigned int len = 0;
        while(a[len])
        {   
                len++;
        }   
        printf("%u\n",len);
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o strlen strl.c
abc@ubuntu:~$ strlen
12

因为这个功能太常用了,所以C语言就加了strlen()这个库函数。

SYNOPSIS   //概要
#include <string.h>  //需要头文件支持。

size_t strlen(const char *s);   //返回一个size_t

示例:

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100]= "hello world!";
        unsigned int len = 0;
       
        len = strlen(a);
        printf("%u\n",len);
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o strlen strl.c
abc@ubuntu:~$ strlen
12

strlen()函数,就是得到字符串的长度,不包含0。它得出字符串的字节数,看示例:

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100]= "hello中国!";
        unsigned int len = 0;
        /*while(a[len])
        {
                len++;
        }
        */
        len = strlen(a);
        printf("%u\n",len);
        return 0;
}

abc@ubuntu:~$ gcc -o strlen strl.c

abc@ubuntu:~$ strlen
14   //hello占5个字节 ,“中国!”3个汉字,在linux(UTF8)中占用9个字节 (3* 3),5+9=14。

 

strcat()函数  字符串追加

看示例:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "hello ";
    char b[100] = "world! ";
    strcat(a,b);
    printf("%s\n",a);

   return 0;
}

运行:

hello world! 

strcat(a,b),这里把a和b的内容合并到a中去,那么,a的空间就要大,大到足够装下b的内容,看示例:
#include <stdio.h>
#include <string.h>

int main()
{
    char a[10] = "hello ";
    char b[255] = "world! abcdefg你好中国!用strcat的时候要注意,第一个字符串一定要有足够的空间容纳第二个字符串";
    strcat(a,b);
    printf("%s\n",a);

   return 0;
}

运行:

用strcat的时候要注意,第一个字符串一定要有足够的空间容纳第二个字符串

strncat()函数  字符串有限追加

strncat最后的整数代表最多追加几个字符

示例:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "hello ";
    char b[255] = "world! abcdefg你好中国!用strcat的时候要注意,第一个字符串一定要有足够的空间容纳第二个字符串";
    //strcat(a,b);
    strncat(a,b,5);
    printf("%s\n",a);

   return 0;
}

运行:

hello world

追加5个字符。

 

strcmp()函数  字符串内容比较

注意返回值:相同返回0,大于返回正数,小于返回负数,C标准中没有硬性规定,但是一般都是1 0 -1 

strcmp(char *s1,char * s2);
     当s1<s2时,返回值<0
        当s1=s2时,返回值=0
        当s1>s2时,返回值>0

看代码示例:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "Hello ";
    char b[100] = "Hello ";
    if( a == b ){;}    //不能通过这种方式比较,因为a和b它们各代表内存地址,不会相同
    if( strcmp(a,b)==0 )    //比较a和b是否相同正确的用法。
    {
        printf("相同\n");    
    }
    else
    {
        printf("不同\n");
    }
   return 0;
}

运行  :

相同

注意:上面高亮部分给出了错误的写法。

 

strncmp()函数  字符串有限比较

指定比较两个字符串的前几个字符,注意返回值:相同返回0,大于返回正数,小于返回负数,C标准中没有硬性规定,但是一般都是1 0 -1

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "Hello ";
    char b[100] = "Hello World!";
    if(strncmp( a,b,6 )==0)
    {
        printf("相同\n");    
    }
    else
    {
        printf("不同\n");
    }
   return 0;
}

运行:

相同

注意高亮部分:判断中后面“==0”来作为条件,如果没有“==0”的话,strncmp()相同时,返回的是0,数字0就是否则,就会运行else下面的“不同”

 

 strcpy()函数 字符串拷贝

strcpy()也存在内存溢出的问题。

*********************************************

SYNOPSIS
#include <string.h>

char *strcpy(char *dest, const char *src);

将源字符串:char *src 拷贝到目标字符串:char *dest中。

*********************************************

没有这个函数,我们自己可以写:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "Hello";
    char b[100] = "World";
    int index = 0;
    while(a[index])
    {
        a[index] = b[index];
        index++;
    }
    printf("%s\n",a);
    return 0;
}

运行:

World

有了strcpy()这个函数,就不用上面的代码了:

{
    char a[100] = "Hello";
    char b[100] = "World";
    /*int index = 0;
    while(a[index])
    {
        a[index] = b[index];
        index++;
    }
    */
    strcpy(a,b);
    printf("%s\n",a);
    return 0;
}

运行:

World

需要注意的是,内存溢出的问题:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[10] = "Hello";
    char b[255] = "World同一个世界,相同的梦想~~~~~~~~~~~~~~~~~~~~~~~!警报:注意内存溢出!!!!!";
    /*int index = 0;
    while(a[index])
    {
        a[index] = b[index];
        index++;
    }
    */
    strcpy(a,b);
    printf("%s\n",a);
    return 0;
}

 

 

 为了避免内存溢出的状况,就有了strncpy()

 

strncpy()函数  字符串有限拷贝

 char *strncpy(char *dest, const char *src, size_t n);

n代表有限拷贝

#include <stdio.h>
#include <string.h>

int main()
{
    char a[11] = "Hello";
    char b[255] = "World同一个世界,相同的梦想~~~~~~~~~~~~~~~~~~~~~~~!警报:注意内存溢出!!!!!";
    //strcpy(a,b);
    strncpy(a,b,5);
    printf("%s\n",a);
    return 0;
}

运行:

World

再看:

#include <stdio.h>
#include <string.h>

int main()
{
    char a[11] = "Hello";
    char b[255] = "World同一个世界,相同的梦想~~~~~~~~~~~~~~~~~~~~~~~!警报:注意内存溢出!!!!!";
    //strcpy(a,b);
    strncpy(a,b,sizeof(a));  //这里把字符数组填满了,成不了字符串了(没有\0)
    printf("%s\n",a);
    return 0;
}

运行:

World同一2�            

没有了\0结尾。

应该写成sizeof(a)-1

#include <stdio.h>
#include <string.h>

int main()
{
    char a[11] = "Hello";
    char b[255] = "Worldaaaaaaaaaaaa";
    //strcpy(a,b);
    strncpy(a,b,sizeof(a)-1);
    printf("%s\n",a);
    return 0;
}

运行:

Worldaaaaa

注意字符串的结尾。

 

sprintf()函数 

sprintf实现将数字转化为字符串的功能

printf是向标准输出设备输出一个字符串
sprintf向一个char的数组输出一个字符串
sprintf的使用方法和printf基本一致,区别是多了第一个参数,第一个参数是一个char的数组
所有printf的转移符对于sprintf是一样的

 

#include <stdio.h>

int main()
{
        char a[100];
        int i = 100;
        sprintf(a,"%s%d","hello world",i);
        printf("%s\n",a);
        return 0;
}

运行:

abc@ubuntu:~$ sprintf
hello world100

相比printf(),sprintf()只是多了一个输出的字符串数组。.

 

sscnaf()函数

ssccanf()相比 scanf()多了第一个参数:char的数组,sscanf()会从这个char的数组中读取相关内容。

 

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "103+105";
    int i,j;
    sscanf(a,"%d+%d",&i , &j );
    printf("%d + %d = %d\n",i,j,i+j );
    return 0;
}

运行:

103 + 105 = 208

从字符串数组里面格式化扫描

 范例:  

#include <stdio.h>
#include <string.h>

int main()
{
    char a[100] = "105/10";
    int i,j,res;
    char c;
    sscanf(a,"%d%c%d",&i , &c , &j );
    switch(c)
    {
        case '+':
            res = i + j ;
            break;
        case '-':
            res = i - j ;
            break;
        case '*':
            res = i * j ;
            break;
        case '/':
            res = i /j ;
            break;
        default : 
            res = 0;
        
    }
    sprintf(a,"%d%c%d = %d\n",i,c,j,res );
    printf("%s",a);
    return 0;
}

 运行:

105/10 = 10

 

 strchr()函数  查找字符


#include <string.h>

char *strchr(const char *s, int c);

在参数char *s中查找参数int c 指定字符,找到返回c在*s在所在位置,没有找到返回NULL;

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100] = "hello world!";
        char *s; 
        s = strchr(a,'w');
        printf("%s\n",s);
    
        return 0;
}

运行:

world!

如果没有要查找的字符呢?最好是有个判断,不为空,就打印:

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100] = "hello world!";
        char *s; 
        s = strchr(a,'w');
        if(s != NULL)
                printf("%s\n",s);
    
        return 0;
}

运行:

world!

strstr()函数  查找字符串

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100] = "hello world!";
        char *s; 
        s = strchr(a,'a');
        if(s != NULL)
                printf("%s\n",s);
        s = strstr(a,"llo");
        printf("%s\n",s);    
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o strchr strchr.c
abc@ubuntu:~$ strchr
llo world!

 

strtok()函数 分割字符串

SYNOPSIS
#include <string.h>

char *strtok(char *str, const char *delim);

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100]= "hello@1234567890@qq.com@zhanguser@password@xxxxx";
        char *s; 
        s = strtok(a,"@");
        printf("%s\n",s);    
        s = strtok(NULL,"@");
        printf("%s\n",s);
        s = strtok(NULL,"@");
        printf("%s\n",s);
        s = strtok(NULL,"@");
        printf("%s\n",s);
        s = strtok(NULL,"@");
        printf("%s\n",s);
        s = strtok(NULL,"@");
        printf("%s\n",s);
        s = strtok(NULL,"@");
        printf("%s\n",s);
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o strtok strtok.c

abc@ubuntu:~$ strtok
hello
1234567890
qq.com
zhanguser
password
xxxxx
段错误 (核心已转储)      //已经没有了,再取就报错。
abc@ubuntu:~$

以上呆笨的写法,只是为了证明:当取值到了最后,已经清空了取不到数据的时候,出现段错误。

那么有没有好的用法呢:

#include <stdio.h>
#include <string.h>

int main()
{
        char a[100]= "hello@1234567890@qq.com@zhanguser@password@xxxxx";
        char *s; 
        s = strtok(a,"@");
        
        while(s)
        {   
                 printf("%s\n",s);
                s = strtok(NULL,"@");
              
        }
        
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o strtok strtok.c

abc@ubuntu:~$ strtok
hello
1234567890
qq.com
zhanguser
password
xxxxx

 完美~!

 

 

atoi()函数 字符串转化为int

 SYNOPSIS

#include <stdlib.h>      //看准用好头文件

int atoi(const char *nptr);

#include <stdio.h>
#include <stdlib.h>

int main()
{
        char a[100]= "300";
        char b[100]= "500";
        int sum = a+b;  //示范错误用法
        sum = atoi(a) + atoi(b);
        printf("%d\n",sum);


        return 0;
}

运行:

abc@ubuntu:~$ gcc -o atoi atoi.c
atoi.c: In function ‘main’:
atoi.c:8:13: error: invalid operands to binary + (have ‘char *’ and ‘char *’)
int sum = a+b; //示范错误用法

正确的用法:

#include <stdio.h>
#include <stdlib.h>

int main()
{
        char a[100]= "300";
        char b[100]= "500";
        int sum = atoi(a) + atoi(b);
        printf("%d\n",sum);
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o atoi atoi.c
abc@ubuntu:~$ atoi
800

在c语言里面提供了把字符串转化为整数的函数,但并没有提供把整数转化为字符串的函数
atoi是标准的库函数
itoa不是c语言标准的库函数

 

atof()函数   字符串转化为float

double atof(const char *nptr);
如何把字符串“abc”和int型数45合并成“abc45”呢?标准C提供atoi,但没有itoa这个函数。那怎么办?试着用strcat函数试下子:

#include <stdio.h>
#include <stdlib.h>

int main()
{
        char a[100]= "300";
        char b[100]= "500";
        int sum = atoi(a) + atoi(b);
        printf("%d\n",sum);
            
        char c[100]= "3.5";
        double f = atof(c);
        char str1[100] = "abc";
        int num = 45; 
        strcat(str1,num);
        return 0;
}

运行报错:

abc@ubuntu:~$ gcc -o atoi atoi.c
atoi.c: In function ‘main’:
atoi.c:16:14: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
strcat(str1,num);
^
In file included from atoi.c:3:0:
/usr/include/string.h:133:14: note: expected ‘const char * restrict’ but argument is of type ‘int’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^
abc@ubuntu:~$ atoi
800
段错误 (核心已转储)

正确的用法是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
        char a[100]= "300";
        char b[100]= "500";
        int sum = atoi(a) + atoi(b);
        printf("%d\n",sum);
    
        char c[100]= "3.5";
        double f = atof(c);
        char str1[100] = "abc";
        int num = 45; 
        //strcat(str1,num);
        sprintf(a,"%s%d",str1,num);
        printf("%s\n",a);
        return 0;
}

运行:

abc@ubuntu:~$ gcc -o atoi atoi.c
abc@ubuntu:~$ atoi
800
abc45

 

atol()函数   字符串转化为long

 long atol(const char *nptr);


 

 字符串分割合成范例:

到底有多少分号是不确定的,如:char a[100] = "120+15=;145-202=;334*2=;1024/64=";

写个程序,执行后=号后面自动添加计算结果。

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char a[100] = "120+15=;145-202=;334*2=;1024/64=";
    char b[100] = { 0 };
    char *s;
    s = strtok(a, ";");
    
    while(s)
    {
        int i, j,res;
        char c;
        char tmp[15];
        sscanf(s,"%d%c%d",&i, &c,&j);
        switch (c)
        {
        case '+' :
            res = i + j;
            break;
        case '-':
            res = i - j;
            break;
        case '*':
            res = i * j;
            break;
        case '/':
            res = i / j;
            break;
        default :
            res = 0;
        }
        sprintf(tmp, "%s%d;", s, res);
        strcat(b, tmp);
        s = strtok(NULL, ";");

    }
    strcpy(a, b);
    printf("%s", a);
    getchar();
    return 0;
}

运行:

 

 

 

转载于:https://www.cnblogs.com/bing-z/p/6195491.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值