顯示具有 string 標籤的文章。 顯示所有文章
顯示具有 string 標籤的文章。 顯示所有文章

9月 12, 2009

const char* 的兩三事

一整個大中招,完全錯誤的寫法如下:
char *str = "hello" ;
*str = "world" ; //想要改變 string 的內容
第一行的宣告,系統會配置空間存放 "hello" 字串。這筆資料是以常態(const)字串儲存,內容不允許更改。所以在第二行指令,希望透過 str 指標來改寫字串內容時,就會有問題。

比較好的方式,應該改採一維陣列來存放資料。當陣列在宣告時,系統會配置一段連續空間以供使用:
char str[30];
strcpy(str, "hello");
strcpy(str, "world");
另外也能使用「二維陣列」來存放資料。使用二維陣列時,因為系統是採 Row-Major 的方式存放資料,所以在函式中務必要提供陣列的維度(Row Dimension,下例中的 SIZE),這樣編譯器才知道如何存取資料。
#define SIZE 20
void set_string(char str[][SIZE])
{
strcpy(str[0], "hello");
}

main()
{
char str[SIZE][SIZE];
set_string(str);
}
另一個更具彈性的做法是,動態分配記憶體(malloc),如此一來參數傳遞時就不用考量到維度的資訊。
void set_string(char **ptr) //直接傳入雙重指標即可
{
strcpy(ptr[0], "hello");
strcpy(ptr[1], "world");
}
main()
{
char *buf[SIZE];
for (int idx=0;idx<SIZE;idx++)
buf[idx]= (char *) malloc(sizeof(char) * SIZE)
set_string(buf);
}
另一個非常重要的觀念,也是回到這篇的主題。在 set_string() 中的指令:
比較下列兩者,不要誤用了:
strcpy(ptr[0], "hello");
ptr[0] = "hello"
使用 strcpy() 是將字串寫到陣列中,陣列空間是當初系統配置的,所以其內容可以任意更改。而後者只是單純「將指標,指向字串」,字串的性質是常數(const),內容不允許修改。

9月 10, 2009

strtok 字串切割函式

UPDATE 9/12:
範例中 gets 宜用 fgets 取代,避免 Buffer Overflow。

將使用者輸入的 String 切割成單一 token 可用 strtok() 這個函式。定義如下:
char * strtok ( char * str, const char * delimiters );
// delimiters 表示以該字元為區隔。
程式使用範例:
char buf[32], token[10][32] , *str;
int idx=0;
gets (buf); //gets 允許輸入的字串帶有空白 (重點)
str = strtok(buf," ");
strcpy (token[0], str);
while ( str != NULL )
{
str = strtok(NULL," "); //此處用 NULL (技巧)
if (str!=NULL)
{
idx++;
strcpy(token[idx], str);
}
}
若輸入:「This is my Blog」,則得到結果:
token[0] = This
token[1] = is
token[2] = my
token[3] = Blog