一个FLAG #22# cstring(1)

例子

1、scanf VS. getchar

#include <cstdio>
#include <cstring>

int main()
{
    char s[20];
    
    while (scanf("%s", s) == 1) {
        printf("echo: %s\n", s);
    }
    // 但是 scanf 会把换行、TAB、空格等全部忽略
    // 特定情况,可采用 getchar() 来解决这个问题 
    
    // Ctrl + Z 进入下一个 while 循环 
    int c;
    while ((c = getchar()) != EOF) {
        printf("echo: %d - %c\n", c, c);
    } 
    
    // 无论怎么输入,输出的最后一行总是 echo: 10 - 然后换两次行 
    // 是因为我们输入的最后一个字符总是换行符 \n 
    // 而 10 恰好对应着 \n 
    return 0;
}

 

2、如何存储字符串字面量

本质而言,C语言把字符串字面量作为字符数组来处理。

C语言编译器在程序中遇到长度为 n 的字面量时,会为其分配长度为 n + 1 的内存空间。

既然是作为字符数组来处理,那么编译器会把字符串字面量看作是 char * 类型的指针。

#include <cstdio>
int main()
{    
    char *s1 = "Hello world\n"; // [Warning] deprecated conversion from string constant to 'char*'
    const char *s2 = "Hello world\n";    
    
    // printf 函数的首个参数类型为 const char * 
    printf(s1);    
    printf(s2);
    printf("Hello world\n"); // 字符串字面量看作 char * 类型指针 
    
    return 0;
}

 

3、初始化字符串变量

#include <cstdio>
int main()
{     
    char s1[5] = "hi"; 
    char s2[5] = {'h', 'i'};
    // 两种初始化方式,效果上是等价的
    // 余下元素被初始化为 0 也就是 '\0'
    
    printf("s1 = %s\n", s1);
    printf("s2 = %s\n", s2); 
    
    // 但是,要注意!
    // char s3[5] = "hi123"; 是不可的,没有给空字符留位子,必须确保数组长度比初始化式的长度 
    // [Error] initializer-string for array of chars is too long [-fpermissive]
    
    char s4[] = "hi";
    // 自动分配 3 个空间,分别存储 'h', 'i', '\0' 
    printf("s4 = %s\n", s4);
    
    return 0;
}

 

4、字符数组 VS. 字符指针

#include <cstdio>
int main()
{     
    // 字符数组可修改! 
    char s1[] = "i hate u !\n";
    s1[2] = 'l';
    s1[3] = 'o';
    s1[4] = 'v';
    s1[5] = 'e';
    printf(s1); // => i love u !
    
    // 字符指针不可以!
    char *s2 = "i hate u !\n"; // 编译报Warning
    // deprecated conversion from string constant to 'char*'
    // s2[2] = 'x'; 可编译但是不可执行 
    printf(s2); // => i hate u !
    const char *s3 = "i hate u !\n"; // 正确的姿势 
    printf(s3); // => i hate u !
    
    // 一个实验。这样是可行的! 
    char s4[] = "i hate u !\n", *s5;
    s5 = s4;
    s5[2] = 'i';
    printf(s5); // => i iate u !
    // 以及之前声明的 const char *s3
    s3 = s4;
    // s3[2] = 'b'; 但是不可更改!报Error 这是因为 s3 是一个 指向const char 的指针
    // 它限制了对 字符数组的操作。
    printf(s3); // => i iate u !
    
    return 0;
}

 

参考

[1] 紫书p45 TeX中的引号

[2] 《C语言程序设计_现代方法 第2版》 第13章 字符串

 

posted @ 2020-05-04 10:36  xkfx  阅读(179)  评论(0编辑  收藏  举报