【小白到大牛之路4】交換機後臺管理之用戶輸入的優化

項目需求

用戶登錄時,用戶可能輸入很長的用戶名。
項目實現

#include <stdio.h>

int main(void) {
    // 定義變量,用來表示用戶名和密碼
    //char name;
    char name[32];
    //int password;
    char password[16];

    // 輸入用戶名和密碼
    printf("請輸入用戶名:");
    //scanf("%c", &name);
    scanf("%s", name);
    printf("請輸入密碼:");
    //scanf("%d", &password);
    scanf("%s", password);

    return 0;
}

項目精講

1.什麼是字符串
什麼是字符串
字符串就是0個或多個“字符”組成的“有序”序列。

字符串長度
字符串包含的字符個數。

字符串結束符
在c語言中,爲了便於存儲字符串,要求在最後一個字符的後面存儲一個0(一個字節)。
這個0, 稱爲“字符串結束符”,常用 ‘\0’ 表示。

“China” => ‘C’ ‘h’ ‘i’ ‘n’ ‘a’ ‘\0’
“” => ‘\0’

字符串常量
字符串常量,要求用“”擴起來。
printf("name=%s", "Rock"); //%s用來匹配字符串

字符串的存儲
在c語言中,字符串是以“字符數組”存儲的。

2.數組的基本概念

什麼是數組
數組,就是多個元素的“組合”。
每個元素的數據類型,必須相同。
每個元素在數組中有一個“下標”,用來表示它在數組中的“序號”,下標從0開始計算。
數組的“容量”是不能改變的。
【小白到大牛之路4】交換機後臺管理之用戶輸入的優化

數組的定義
數組和其他變量一樣,需要先定義,再使用。

實例:
int a[8]; //定義了一個數組,數組名是“a”,包含8個元素,每個元素是int類型的變量
a[0] = 20;
a[1] = 5;
printf(“%d”, a[1]);

char num[8];

數組的初始化

在定義數組的同時,設置數組內的元素值。

int a[8] = {20, 5, 30, 13, 18};
printf("%d,%d,%d,%d,%d\n", a[0],a[1],a[2],a[3],a[4]);

int a[8] = {0}; //把數組的所有元素都初始化爲0
printf("%d,%d,%d,%d,%d\n", a[0],a[1],a[2],a[3],a[4]);

int a[8] = {1}; //把a[0]初始化爲1,其它值都初始化爲0
int b[8] = {1, 5}; //把a[0]初始化爲1,a[1]初始化爲5,其它值都初始化爲0

int a[] = {1,2,5}; //定義數組a, 這個數組包含3個元素!
// 根據“初始化列表”,自動計算數組的容量
常見錯誤

int a[2] = {1,2,5}; //錯誤!初始值太多,大於數組的容量

int a[3];
a = {1, 2, 3}; //不能對數組名直接賦值!

int a[3];
a[3] = 10; //下標越界!下標的取值範圍是 0, 1, 2
數組的內元素的訪問
通過下標訪問對應的元素。
特別注意, 數組的第一個元素的下標是0, 而不是1

int a[10];
a[5] = 200;
printf(“%d\n”, a[5]);

數組的越界
數組的越界, 是指下標超出正常的範圍!
例如:
int a[10]; //a[-1] 和 a[10]都是越界!

越界的後果
越界非常危險,可能導致數據破壞,或其他不可預期的後果!

越界的控制
需要程序員自己手動控制,編譯器不做任何檢查!因爲,C語言完全信任程序員!

3.字符串的存儲

字符串,是通過“字符數組”(元素類型爲char的數組)來存儲的!

demo1

    char  name[10];
    name[0] = 'R';
    name[1] = 'o';
    name[2] = 'c';
    name[3] = 'k';
    name[4] = 0;  //字符串結束符0,就是 '\0'
    printf("姓名:%s", name);  // 

name[2] = 0;
    printf("姓名:%s", name);   //

demo2

    char  name[10] = "Rock"; //相當於char name[10] = {'R', 'o', 'c', 'k', '\0'};
    printf("姓名:%s", name);

demo3

char  name[] = "Rock";  //相當於:name[5] = "Rock"
    printf("%d", sizeof(name)); //5

4.字符串的輸入

scanf
從第一個非空白字符開始讀取,直到遇到空白字符爲止(不包含空白字符)

demo1

    char name[16];
    scanf("%s", name);    //輸入 Rock polo  
    printf("%s", name);    //輸出 Rock

缺點:
1.不能讀取空格、製表符,因爲被當作“分隔符”處理了!
2.可能導致越界。
gets
遇到回車符結束,相當於讀一行,但是不包括行末的回車符。

demo2

char name[16];  
    gets(name);          // 輸入  Rock polo
    printf("%s", name);    // 輸出  Rock polo

特點:
1.能夠讀取 空格、製表符,但是不讀取回車符。
2.使用方便。

fgets

讀取一行,直到遇到回車符。
demo1

    char name[8];

    fgets(name, 8, stdin); 
    //最多讀8個字符,除去末尾的字符串結束符,實際最多隻有7個字符
    //輸入1234567890  name的值爲:"1234567\0" 
    //輸入12345       name的值爲:"12345\n\0" 

特點:
1.安全!
當輸入數據太多時,就只讀取(第二個參數 -1)個字符
2.回車符也被讀到字符串(除非輸入數據太多)

注意:
fgets函數的第2個參數,常常使用sizeof
demo2

    char name[8];
    fgets(name,  sizeof(name), stdin); 

5.字符串的輸出

printf使用%s

實例:略

6.常用的字符串函數

計算字符串的長度

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

int main(void) {
    char name[] = "Rock";
    printf("len = %d\n", strlen(name));  //len = 4

    return 0;
}

字符串拷貝strcpy

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

int main(void) {
    char name1[] = "Rock";
    char name2[32];

    strcpy(name2,  name1);  //把字符串name1拷貝到字符串name2
    printf("name2=%s", name2);

    return 0;
}

strcpy的特點:
把源字符串的“字符串結束符”也一同拷貝到目的字符串中

strcpy的缺點:
可能導致字符串越界!不安全

字符串拷貝strncpy

demo1

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

int main(void) {
    char str1[10] = "123456789";
    char str2[10] = "abcdefghi";

    strncpy(str1, str2, 3);   //從str2拷貝3個字符到str1
    printf("str1=%s", str1);  //str1=abc456789

    return 0;
}

demo2

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

int main(void) {
    char str1[10] = "123456789";
    char str2[10] = "ab";

    strncpy(str1, str2, 5);   //從str2拷貝5個字符到str1
    printf("str1=%s", str1);  //str1=ab
                        //str1數組的值:'a','b',0,0,0,'6','7','8','9', 0

    return 0;
}

當strncpy的第3個參數,大於拷貝源(第二個參數)的長度+1時,則把不足部分用0填充!!!

字符串連接strcat
demo

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

int main(void) {
    char dest1[64];
    char dest2[64];

    printf("請輸入您的省份: ");
    gets(dest1);
    printf("請輸入您的城市: ");
    gets(dest2);

    strcat(dest1, dest2);

    printf("str1: %s\n", dest1);
    printf("str2: %s\n", dest2);

    return 0;
}

    printf("請輸入您的省份: ");
    gets(dest1);
    printf("請輸入您的城市: ");
    gets(dest2);

    strcat(dest1, dest2);

    printf("str1: %s\n", dest1);
    printf("str2: %s\n", dest2);

    return 0;
}

還有很多其它字符串函數,需要用的時候,再學習。

項目練習

1.獨立實現該項目。
2.要用戶輸入5個整數,保存到一個數組中。然後計算這個數組的平均值。
3.要求用戶輸入一個人的姓名,然後輸出這個字符串的長度。

項目討論
該項目存在的問題:
當用戶輸入的用戶名超過31個字符時,導致數組越界。
當用戶輸入的密碼超過15個字符時,導致數組越界。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章