C 語言筆記 — 字串(Strings)
字串其實就是字元的集合,還記得字元代表一個字母的意思吧。字串就是一個單詞的概念。
字元:A
字串:Apple
本章重點:
- 字串的宣告
- 字串的輸入、輸出
- 函式 sprintf, sscanf
- <string.h> 應用
- 字串轉換成數字
1. 字串的宣告
字串在C語言中,以陣列的形式表現,並且用 ‘ \0 ’ 作為結束符號。
字串的宣告如下:
char 字串名稱[字串長度] = “Apple”;
當你宣告字串時,編譯器會自動在字串的最後一個後面加上’ \0 ’(告訴電腦說我們這詞彙已經結束)
還有其他種宣告方式:
char str1[ 6 ] = "hello";
char str2[] = "starbucks"; // size 10//一般的陣列宣告也適用,只是要注意會多一項‘\0’
char str3[ 6 ] = {'h', 'e', 'l', 'l', '0', '\0'};
char str4[] = {'s', 't', 'a', 'r', 'b', 'u', 'c', 'k', 's', '\0'};
*str1陣列大小設為 6的原因是,我們還需要考慮最後一個 ’ \0 ’ 他也算是一個字元,所以要多加1
*str2的例子中,我們可以知道,就算不設陣列大小也是可以宣告字串。
*重點小結:
.宣告字串時,要用雙冒號。ex : “hello”
.字元,單引號不會視為字串。ex : ’A’
.就像一般陣列來說,字串也可以作為指標使用。
.字串指標 ex: char *str = “hello”; hello會被視為常數(不可以做修改)。
2. 字串的輸入、輸出 (String Input / Output)
— 輸入(String Input):
之前我們有提過,C提供的輸入有scanf() , gets(), fgets(),那現在我們該如何運用在字串上呢?
舉例來說明:
- scanf:
char name[20];
int age;printf("Please enter your name and age\n");
scanf("%s %d", name, &age);
用scanf()讀取字串,注意字串name前面不需要加記憶體位置‘&’,因為陣列名稱就有指標的概念。
*當讀取到空白的時候scanf()會自動結束。所以我們可以用gets(),因為gets()讀取到enter(newline)時,才會結束。
之前有提過使用gets()比較不安全,fgets()會是更好的選擇。
- fgets的使用:
fgets(陣列(字串)名稱, 想要讀取的數量大小, stdin)//stdin標準輸入,也可以說是從鍵盤讀取的概念。
範例:
#include <stdio.h>
#include <string.h>int main()
{
char name[20];
fgets (name, 20, stdin);
puts(name); return 0;
}
*注意:fgets()會在輸出時,自動多加換行\n。
若想要把換行去掉的話可以打以下程式碼:
char name[20];if( name[strlen(name) - 1] == '\n')
name[strlen(name) - 1] == '\0';// 意思就是把原本放在後面的換行,變成終止符號,就不會自動換行了。
— 輸出(String Output):
fputs(), puts(), printf()都是輸出的好幫手。
printf()相信大家都很熟練了,這邊就不多做說明。
- fputs的使用:
fputs需要字串名稱和一個指標指出要在哪裡印出字串,在下面的程式碼指標為stdout,因為我們要印在螢幕上,所以使用標準輸出。
#include <stdio.h>
#include <string.h>int main()
{
char name[20];
fgets (name, 20, stdin);
fputs(name, stdout); return 0;
}
- puts()的使用:
#include <stdio.h>
#include <string.h>int main()
{
char name[20];
fgets (name, 20, stdin);
puts(name); // 會自動換行 return 0;
}
3. 函式sprintf, sscanf
- sprintf
用途:將不同的資料型態轉換成字串(string)
範例:
#include <stdio.h>int main()
{
char weather[100];
char country[ ] = "Japan";
int tmp= 20; // 雙括弧內有字串也有整數,將他們整合成字串放入weather中。
sprintf(weather, "%s is about %d degrees.", country, tmp); printf("%s\n", weather);
return 0;
}
- sscanf
用途:讀取字串,並個別放入新的字串中。
#include <stdio.h>
int main()
{
char test[100] = "100 math";
char object[10];
int grade; //讀取字串test中100和math,並且個別存入grade跟object中
sscanf(test, "%d %s", &grade, object); printf("%s: %d\n", object, grade); return 0;
}
*注意:因為是整數,所以grade前面要加上 ‘ & ’,代表存入grade的記憶體位址中。
4. <string.h>應用
為了可以更安全及方便的使用字串,C 語言提供標準函式庫<string.h>讓我們使用。有幾個比較好用的提供給大家參考:
- strlen() — 得到字串長度
這邊計算長度,不會把終止符號一起算進去,很單純只有字串的長度。
- strcat() — 合併兩個字串
char * strcat ( char * destination, const char * source );//翻成中文來看
char * strcat ( char * 合併到的字串, 被合併的字串(const));
- strncat(str1(被合併的字串), str2(原本的字串), n)
— 將str2的前n個字母合併到str1上
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[20];
char str2[20];
strcpy (str1,"How are ");
strcpy (str2,"you. I fine thank you."); strncat (str1, str2, 4); //將str2中前4個字母合併到str1上
puts (str1);
return 0;
}
- strcpy() — 複製字串
- strncpy(str1, str2, n) — 從第str2中的第n個字母複製到str1上
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]= "To be or not to be";
char str2[40];
char str3[40];
strncpy ( str2, str1, sizeof(str2) ); // 將str1複製到str2上。
/* 只複製五個字母 */
strncpy ( str3, str2, 5 ); //str2中的前五個字母複製到str3上。 str3[5] = '\0'; /* 在str3上加一個結束符號 */
puts (str1);
puts (str2);
puts (str3);
return 0;
}
source from : cpp
- strcmp() — 比較兩個字串
字串比較的方式,從第一個字母開始必較,若第一個字母相同的話,就換用第二個字母去做比較,以此類推。
#include <stdio.h>
#include <string.h>int main ()
{
char str1[20] = "banana";
char str2[20] = "apple";int cmp = strcmp(str2, str1);
if(cmp > 0) //str1 > str2
{
printf("%s > %s", str1, str2);
}
else if (cmp == 0) // str1 = str2
{
printf("%s = %s", str1, str2);
}
else if (cmp < 0)// str1 = str2
{
printf("%s < %s", str1, str2);
}return 0;
}
一開始先比第一個字母,字母b再ascii code中比字母a還要小,所以比較之後會是小於的結果。
比較方式:
int cmp = strcmp(str2被比對的字串, str1要比對的字串);
str1 > str2,回傳 >0的值
str1 == str2,回傳 =0的值
str1 < str2,回傳 <0的值
更多資訊可以參考:cpluscplus
- strncmp(str1, str2, n)
回傳=0,當 str1的前n個 = str2的前n個相同
回傳>0,當 str1的前n個 > str2的前n個
回傳<0,當 str1的前n個 < str2的前n個
#include <stdio.h>
#include <string.h>
int main ()
{
char str[][5] = { "AABC" , "BBCA" , "AACA", "AABCD" };
int n;
puts ( "前面是AA的有..." );
for (n = 0 ; n < 4 ; n++)
{
//如果str[n]和AAxx前面兩個字母(AA)相同
if ( strncmp (str[n],"AAxx",2) == 0 ) )
{
printf ( "found %s\n",str[n] );
}
}
return 0;
}
- strchr(str1, c) — 回傳字母 c 在str1上的哪一個位置
*當沒找到字母c,就會回傳NULL
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch; //宣告指標(存記憶體位址) printf ("Looking for the 's' character in \"%s\"...\n",str);
pch = strchr(str,'s'); //把str字串中,第一個出現s的記憶體位址存到*pch中 while (pch != NULL)
{ //將找到s的記憶體位址減去字串str的第一個位址再加上1就會是字串中的第幾個位子。
printf ("found at %d\n", pch - str + 1);
/*在找下一個s的位址,用原本的記憶體位址再加一(下一個字串)也就是從
“ is a sample string” 開始找下一個s,以此類推 */
pch = strchr( pch + 1,'s' );
}
return 0;
}
source from : cpp
- strrchr(str1, c) — 倒著找回來字母 c 在str1上的哪一個位子
*跟上方類似,只是從後面找回來
*當沒找到字母c,就會回傳NULL
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
pch = strrchr(str,'s');
// s 最後出現在哪一個位址
printf ("Last occurence of 's' found at %d \n", pch - str + 1);
return 0;
}
source from : strrchr
- strstr(str1, str2) — 回傳一個指標,指標內容是在str1中第一次出現的str2,如果沒找到則回傳NULL值
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a simple string";
char * pch;
pch = strstr (str,"simple"); //在str中找到字串"simple"並存入pch中
strncpy (pch,"sample",6); //將sample字串複製到pch中
puts (str);
return 0;
}
*因為是直接把記憶體位址換掉,所以字串str中”simple”也會直接改變。
source from : strstr
5.字串轉換成數字
有幾種方式可以把字串轉成數字:
- atoi , ACSII convert to integer
- atof , ACSII convert to float
- atol , ACSII convert to long integer
要使用前,要先include<stdlib.h>
範例:
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atoi */
int main ()
{
int a;
char memory[256]; printf ("Enter a number: ");
fgets (memory, 256, stdin);
a = atoi (memory);
printf ("The value entered is %d. Its double is %d.\n", a, a*2);
return 0;
}
*在最底下我們可以看到a * 2的運算,代表說我們已經將原本的字串轉換成整數型態。
source from : atoi
其他範例可以去cplusplus查看,那裡有豐富的資源等著你~~
終於把字串講完拉~如果有不懂的也歡迎提問,其實之後多做題目就可以把這些東西融會貫通了。繼續朝著C語言之路邁進吧!!