<C语言|字符串函数总结>

C语言|字符串函数总结

  • 字符串I/O
    • puts vs printf
    • 在程序中定义字符串
      • 字符串字面量(字符串常量)
      • 字符串数组和初始化
        • 字符串 vs 字符数组
      • 数组和指针
      • 数组和指针的区别
      • 字符串数组
    • 指针和字符串
  • 字符串输入
    • 分配空间
    • gets() vs scanf()
    • gets()的替代品
      • fgets() 函数(和fputs())
      • gets_s()函数
      • s_gets()函数
    • scanf()函数
  • 字符串输出
    • puts()函数
    • fputs()函数
    • printf()函数
    • 自定义函数
  • 字符串函数
    • strlen()函数
    • strcat()函数
    • strncat()函数
    • strcmp()函数
    • strncmp()函数
    • strcpy()函数
    • strncmp()函数
    • sprintf()函数
  • ctype.h中的函数

写在前面:本文基于上课所用PPT及《C Primer Plus》第6版,代码也是多源于此。字符串函数一直是本人弱项,终于熬过了考试周,来总结一下为C语言的期末机试做准备。

字符串:以==空字符(\0)==结尾的char类型数组。

字符串I/O

puts vs printf

put()函数只显示字符串,自动在显示的字符串末尾加上换行符

#include

#define MSG "I am a symbolic string constant."
#define MAXLENGTH 81

int main (void) {
    char words[MAXLENGTH] = "I am a string in an array.";
    const char *pt1 = "Something is pointing at me.";
    puts ("Here are some strings:");
    puts ("using puts:");
    puts (MSG);
    puts ("using printf:");
    printf ("%s", MSG);
    puts (pt1);
    return 0;
}

结果为:printf()函数不输出换行符
字符串的初始化不需要使用{}

在程序中定义字符串

字符串字面量(字符串常量)

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

字符串数组和初始化

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

字符串 vs 字符数组

const char m1[40] = " Limit yourself.";
const char m2[40] = " 'L', 'i', 'm', 'i', 't', ' ', 'y', 'o', 'u', 'r', 's', 'e', 'l', 'f', '.', '\0'};
const char m3[40] = " 'L', 'i', 'm', 'i', 't', ' ', 'y', 'o', 'u', 'r', 's', 'e', 'l', 'f', '.'};

m1,m2是字符串,m3是字符数组,因为末尾无’\0’。

制定数组大小时,要确保数组的元素个数至少比字符串长度多1。所有未被使用的元素都被自动初始化为0(char形式的空字符)。

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

const char m1[] = " Limit yourself.";

数组和指针

通常,字符串都作为可执行文件的一部分储存在数据段中。当把程序载入内存时,也载入了程序中的字符串。字符串储存在静态存储区(static memory)中。但是,程序在开始运行时才会为该数组分配内存。此时,才将字符串拷贝到数组中。此时字符串有两个副本,一个是在静态内存中的字符串字面量,另一个是储存在ar1数组中的字符串。
在数组形式中,ar1是地址常量,…

数组和指针的区别

字符串数组

指针和字符串

字符串输入

分配空间

char *name;
scanf ("%s", name);

可能会通过编译(可能给出警告),读入name时可能会擦写掉程序中的数据或代码,从而导致程序异常终止。因为scanf()要把信息拷贝至参数指定的地址上,而此时该参数是个未初始化的指针,name可能指向任何地方。
最简单的方法是,在声明时显式指明数组的大小;

gets() vs scanf()

scanf()函数和%s转换说明只能读取一个单词,遇空格停止。
gets()读取整行输入,直至遇到换行符,然后丢弃换行符,储存其余字符,并在这些字符的末尾添加一个空字符使其成为一个C字符串。经常和puts()配对使用。
**gets()无法检查数组是否装得下行。**如果输入的字符串过长,会导致缓冲区溢出(buffer overflow),即多余的字符超出了指定的目标空间。如果这些多余的字符只是占用了尚未使用的内存,就不会立即出现问题;如果它们擦写掉程序中的其他数据,会导致程序异常中止;或者还有其他情况。

gets()的替代品

fgets() 函数(和fputs())

空字符vs空指针

gets_s()函数

s_gets()函数

scanf()函数

scanf()从第一个非空白字符作为字符串的开始。如果使用%s说明,以下一个空白字符(空格、空行、制表符或换行符)作为字符串的结束(字符串不包括空白字符)。如果制定了字段宽度,如%10s,那么scanf()将读取第10个字符或读到第1个空白字符停止(先满足的条件即是结束输入的条件)。

字符串输出

puts()函数

函数在遇到空字符时停止输出,所以必须确保有空字符

fputs()函数

printf()函数

自定义函数

字符串函数

strlen()函数

用于统计字符串的长度。需要#include

strcat()函数

strcat()函数用于拼接字符串,接受两个字符串作为参数。该函数把第2个字符串的备份附加在第1个字符串末尾,并把拼接后形成的新字符串作为第1个字符串,第2个字符串不变。strcat()函数的类型是char*,返回第1个参数,即拼接第2个字符串后的第1个字符串的地址。

#include
#include
#define SIZE 80
char * s_gets (char * st, int n);
int main (void) {
    char flower[SIZE];
    char addon [] = "s smell like old shoes.";

    puts ("What is your favorite flower?");
    if (s_gets (flower, SIZE)) {
        strcat (flower, addon);
        puts (flower);
        puts (addon);
    }
    else {
        puts ("End of file encountered!");
    }
    puts ("bye");
    return 0;
}

char * s_gets (char * st, int n) {
    char * ret_val;
    int i = 0;

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

no

strncat()函数

strcat()函数无法检查第1个数组是否能够容纳第2个字符串。如果分配给第1个数组的空间不够大,多出来的字符串溢出到相邻存储单元是就会出现问题。

strcmp()函数

int strcmp (const char *str1, const char *str2);

返回值:负整数/0/正整数

#include
#include

int main (void) {
    char name1[50], name2[50];
    int diff;
    printf ("Name of Country 1:");
    gets (name1);
    printf ("Name of Country 2:");
    gets (name2);
    diff = strcmp (name1, name2);
    if (diff > 0) {
        printf ("%s > %s\n", name1, name2);
    }
    else {
        printf ("%s <= %s\n", name1, name2);
    }
    return 0;
}

在这里插入图片描述
strcmp函数比较的是字符串,不是整个数组。可以用来比较储存在不同大小数组中的字符串。字符串1>2,返回负数。
在某些情况下,可用strcmp()函数来处理结束输入的情况,如strcmp(str,"***end***")==0

strncmp()函数

可以比较到字符不同的地方,也可以只比较第3个参数指定的字符数。例如,查找以"astro"开头的字符串,可以限定函数只查找这5个字符。strncmp(list[i],"astro",5)

strcpy()函数

#include
#include

int main (void) {
    char name[50], bakName[50];
    puts ("input a name:");
    gets (name);
    strcpy (bakName, name);
    printf ("You input is %s\n",bakName);
    return 0;
}

把第2个字符串拷贝给第1个字符串。储存第1个字符串的数组需要有足够的空间。
1.strcpy的返回值是第1个参数的值
2.第1个参数不必指向数组的开始,可以用于拷贝数组的一部分。

strncmp()函数

sprintf()函数

ctype.h中的函数

int isalnum(int c):判断是否有数字及字母
int isalpha(int c):判断是否有字母
int isdigit(int c):判断是否是十进制数字
int islower(int c):判断是否是小写字母
int isupper(int c):判断是否是大写字母
int tolower(int c):转化成小写字母
int toupper(int c):转换成大写字母

你可能感兴趣的:(C语言学习笔记,字符串,c语言)