用戶登陸時,用戶可能輸入很長的用戶名。
項目實現程序員
#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’ 表示。 ide
「China」 => ‘C’ ‘h’ ‘i’ ‘n’ ‘a’ ‘\0’
「」 => ‘\0’函數
字符串常量
字符串常量,要求用「」擴起來。
printf("name=%s", "Rock"); //%s用來匹配字符串學習
字符串的存儲
在c語言中,字符串是以「字符數組」存儲的。優化
什麼是數組
數組,就是多個元素的「組合」。
每一個元素的數據類型,必須相同。
每一個元素在數組中有一個「下標」,用來表示它在數組中的「序號」,下標從0開始計算。
數組的「容量」是不能改變的。
3d
數組的定義
數組和其餘變量同樣,須要先定義,再使用。code
實例:
int a[8]; //定義了一個數組,數組名是「a」,包含8個元素,每一個元素是int類型的變量
a[0] = 20;
a[1] = 5;
printf(「%d」, a[1]);blog
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語言徹底信任程序員!
字符串,是經過「字符數組」(元素類型爲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
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.使用方便。
讀取一行,直到遇到回車符。
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);
printf使用%s
實例:略
計算字符串的長度
#include <stdio.h> #include <string.h> int main(void) { char name[] = "Rock"; printf("len = %d\n", strlen(name)); //len = 4 return 0; }
#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的缺點:
可能致使字符串越界!不安全
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個字符時,致使數組越界。