美文网首页
09 重忆C之 字符串

09 重忆C之 字符串

作者: 夏威夷的芒果 | 来源:发表于2017-08-29 16:09 被阅读13次

    在之前的学习中,我们曾经使用过printf函数对字符串进行输出。那么,如果我们希望输入一个字符串到变量,我们可以怎么做呢?

    第一种:scanf
    希望接收一个字符串到string这个变量。可以使用scanf("%s", string);这里写的并不是&string而是string。因为在 C 语言中,数组名直接可以被当做数组所在内存的地址使用。输出的时候可以使用printf("%s\n");来输出
    对于如下代码:

    #include <stdio.h>
    int main() {
        char string[10];
        // 请在这里使用 scanf
        scanf("%s", string);
        printf("%s\n",string);
        return 0;
    }
    

    点击 运行 测试一下程序,看看如果你输入hello worlditisverylongforittostore分别会有怎样的结果?

    当输入hello world时,被输出的只有hello。这是因为scanf在遇到空格时就已经终止读入了。

    当输入一个很长的字符串时,就出现了 Segmentation Fault(段错误)。因为声明的字符数组长度只有 10,我们已经在程序运行时,让它写入了“不属于它”的内存空间。

    来看看第二种:

    嵌入占位符

    #include <stdio.h>
    
    int main() {
        char information[100];
        char *name = "Li, Lei";
        char *gender = "male";
        int age = 14;
        float height = 187.5f;
        // 在这里使用 sprintf
        sprintf(information, "%s is a %s. He is %d-year-old and %fcm tall.", name, gender, age, height);
        printf("%s", information);
    }
    

    输出为
    Li, Lei is a male. He is 14-year-old and 187.500000cm tall.

    sprintfinformation这一字符串中写入了一个格式化输出的结果,依照字符串格式描述,一系列intfloat等类型的数据被“嵌入”到了格式字符串的占位符位置,并最终写入到了information中。
    即将一系列的变量按照指定格式写入到一个字符串中。

    sprintf可用于各种数据的格式化:

    • 第一个参数是被写入的字符串;
    • 第二个参数是写入的格式;
    • 之后的参数是依次会被写入的数据。

    在这里要提醒一下,我们一定要注意用于第一个参数的字符串声明时的长度,如果它所对应的内存空间不足,我们现在的这种用法就可能会触发段错误。

    字符串长度

    头文件#include <string.h>
    使用方法:

    strlen(字符串字面量或者变量)    //返回得到的是其长度(不带末位\0)
    

    复制字符串

    strcpy(copy, string);       //第二个参数是被复制的字符串,第一个参数是需要复制到的目标字符串变量位置
    

    在程序中通过strcpy完成了复制的过程后,copy中就和string中的字符串是一致的了。

    要注意一下,在使用strcpy时要确保目标字符串的声明长度可以装得下,否则程序运行时则可能会出现段错误。

    为避免此问题,在工程中更多的鼓励使用增加了第三个“复制长度”参数的strncpy函数。即只把前n个字符复制上去。

    字符串的字典序(比较)

    在数学中诸如 10 < 20这样数字的大小关系是天然定义的,可是对于字符、字符串来说,他们有“大小”关系吗?

    当我们把"China"和"America"放在一起的时候,我们可以说它们这两个字符串其中有一个大于另外一个么?这个问题的回答是——“有”。

    C 语言中对于字符的比较依赖的是字符的编码,C 语言中默认使用了 ASCII(American Standard Code for Information Interchange,美国标准信息交换码)作为编码标准,每一个字符都对应了一个整数值。常见的一些字符和他们对应的编码值如下:

    ASCII码

    通过参考列出的 ASCII 码参考表(局部),在 C 语言中,字符直接进行大小的比较时,会对它们的编码值进行比较。因此,'A'小于'B','A'小于'a'。

    C 语言中,通常遵循一种特殊定义——字典序(lexicographical order)。
    说白了就是后面的比前面的大,有比没有大。
    "abc" < "bbc"

    • 对于字符串"abc""bbc"的大小关系——
      我们首先会对它们的第一个字符进行比较,
      我们发现第一个字符'a'< 'b'时,
      我们就可以明确"abc" <"bbc"的结论。

    "abc" < "abd"

    • 对于字符串"abc""abd"的大小关系——
      我们首先会对它们的第一个字符进行比较,
      如果第一个字符相同,则会接下来比较第二个字符;
      如果第二个字符相同,则会接下来比较第三个字符,
      当我们发现第三个字符'c'<'d'时,我们就得到了"abc"< "abd"的结论。

    "ab" < "abc"

    • 对于字符串"abc""ab"的大小关系——
      我们首先会对它们的第一个字符进行比较,
      如果第一个字符相同,则会接下来比较第二个字符;
      如果第二个字符相同,则会接下来比较第三个字符,
      当我们发现"ab"没有第三个字符时,我们就得到了"ab"< "abc"的结论。

    总结:

    • 字典序遵循 逐字符比较的方式,越靠左的字符越会被先比较。
    • 逐字符比较过程中,一旦发现某一对被比较的字符之间不相等时,这一对字符的大小关系即为这一对字符串的大小关系。
    • 逐字符比较过程中,一旦出现某一个字符串的所有字符都已经经过比较,而另一字符串还存在未被比较的字符时,较短的字符串更小。
    • 如果所有字符串内的字符都被发现相等,则这两个字符串相等。
      因此,字符串"China"大于"America"。

    比较的语句 strcmp(input, string);

    input小于string时返回了负数,当input等于string时返回了 0,当input大于string时返回正数呢?

    我们可以通过在if的条件中写:
    strcmp(input, string) == 0
    来判断两个字符串是否相同。也可以将等号改为大于号、小于号来判断字符串的大小关系。

    问题:

    输入 10行不含有空格的字符串,对应十个学生姓名(长度大于 0 小于 20)。
    输出为 101行,为排序后的 10 个学生姓名,每个学生姓名单独占一行。

    样例输入

    Alice
    Bob
    Gary
    Harry
    Ivn
    Julia
    Danis
    Fone
    Candy
    Evan
    

    样例输出

    Alice
    Bob
    Candy
    Danis
    Evan
    Fone
    Gary
    Harry
    Ivn
    Julia
    

    代码

    #include <stdio.h>
    #include <string.h>
    void swap(char a[20], char b[20]){
        char c[20];
        strcpy(c, a);
        strcpy(a, b);
        strcpy(b, c);
    }
    int main() {
        char arr[10][20];
        int i,j;
        for (i = 0; i < 10; i++){
            scanf("%s",arr[i]);
        }
        for (i = 0; i < 10; i++ ){
            for (j = 0; j < 9; j++){
                if (strcmp(arr[j],arr[j+1])>0){
                    swap(arr[j],arr[j+1]);
                }
            }
        }
        for (i = 0; i < 10; i++){
            printf("%s\n",arr[i]);
        }
    }
    

    字符串拼接

    strcat(A, B);会把参数的第二个字符串(含\0)加在第一个字符串的/0位置
    strcat函数将第二个参数的字符串(含\0)拷贝到第一个参数的字符串\0所在内存位置及之后。所以,我们通过

    strcat(hello, world);
    就会改变hello的值,让"hello "之后多出了"world"这段字符串
    (假设char hello[100] = "hello "; char world[100] = "world";)。

    类似于strcpy函数,在使用strcat函数时,也要注意内存安全问题。如果被连接上新内容的目标字符串的声明长度不够长,程序就可能出错。相应工程中也更鼓励使用增加了第三个“追加长度”参数的strncat函数,即只把前n个字符拼上去。大家可以通过搜索引擎具体了解一下。

    相关文章

      网友评论

          本文标题:09 重忆C之 字符串

          本文链接:https://www.haomeiwen.com/subject/gpjgdxtx.html