作者: haloPaul 時間: 2018-12-22 12:33 標題: C語言字串結合功能
本帖最後由 haloPaul 於 2018-12-22 12:35 編輯
在C語言裏面,有一個字串結合功能strcat(str1, str2);可以調用
但是,我想靠自己寫一個一模一樣的功能出來,而不用strcat(str1, str2);這個內部提供的功能。
以下的程式碼是我寫的,但是運行結果不對。請問如何實現這個字串結合功能?
#include <stdio.h>
int main() {
char dataA[30]; //first data
char dataB[30]; //second data
char finalData[60]; //concate data
int i = 0;
printf("Please enter a text: ");
while (1) {
scanf("%s", &dataA); //read in 1st data
scanf("%s", &dataB); //read in 2nd data
finalData[60] = dataA[30] + dataB[30];
printf("The link of text is %s ", finalData);
}
return 0;
}
作者: EITCo 時間: 2018-12-22 17:11
本帖最後由 EITCo 於 2018-12-22 17:16 編輯
你可能寫慣其他更高階的語言,有得就咁 cat = str_a + str_b
C相對較低階,無咁直覺,資料的格式同運算都更貼近硬件層面
C的string其實只係char[],所以concat string其實即係concat array
如果擺脫唔到既有 str_a + str_b 的諗法
可以想像依家係做緊concat int[]
- int a[6] = { 0, 10, 20 };
- int b[] = { 30, 40, 50 };
- int a_len = 3, b_len = 3, i;
- for (i = 0; i < b_len; i++) {
- a[a_len + i] = b[i];
- }
以上都先寫左將b駁係a後面的版本
然後轉返做char[]
另外string有最尾的 '\0' 要注意
而string長度如果唔用strlen,亦係靠數 '\0' 係第幾個char
- char *my_strcat(char *dest, const char *src) {
- // Find length of dest
- // Can also use strlen(dest)
- int dest_len = 0;
- while (dest[dest_len] != '\0') {
- dest_len++;
- }
- // At this point, dest[dest_len] == '\0'
- // It will be overriden by src[0] in the below loop
- int i;
- for (i = 0; src[i] != '\0'; i++) {
- dest[dest_len + i] = src[i];
- }
- // Put null char at the new end of dest
- dest[dest_len + i] = '\0';
- return dest;
- }
另外以下省略左啲 != '\0'
- char *my_strcat_2(char *dest, const char *src) {
- char *char_p = dest;
- while (*char_p) {
- char_p++;
- }
- while (*src) {
- *char_p++ = *src++;
- }
- *char_p = '\0';
- return dest;
- }
而上面第7至10行需要用兩次,所以寫個function (其實即係strcpy)
- char *my_strcpy(char *dest, const char* src) {
- while (*src) {
- *dest++ = *src++;
- }
- *dest = '\0';
- return dest;
- }
- char *my_alloc_strcat(char *head, char *tail) {
- int head_len = strlen(head);
- char *concat = malloc(sizeof(char) * (head_len + strlen(tail) + 1));
- my_strcpy(concat, head);
- my_strcpy(concat + head_len, tail);
- return concat;
- }
char dataA[30]; scanf("%s", &dataA);
應該無 & 先岩,因為 dataA 已經係一個地址
有別於以下要 &i, &c 先係地址
int i; scanf("%d", &i);
char c; scanf("%c" &c);
作者: EITCo 時間: 2018-12-22 17:31
補埋示範
- void print_triple(char *str_0, char *str_1, char *str_2) {
- printf(""%s"\n"%s"\n"%s"\n\n", str_0, str_1, str_2);
- }
- int main() {
- char a[4 + 3 + 1] = "abcd"; // + 1 for '\0'
- char b[] = "efg";
- char *c = my_strcat(a, b);
- print_triple(a, b, c);
- // "abcdefg"
- // "efg"
- // "abcdefg"
- char d[] = "hijk";
- char e[] = "lmn";
- char *f = my_alloc_strcat(d, e);
- print_triple(d, e, f);
- // "hijk"
- // "lmn"
- // "hijklmn"
- return 0;
- }
作者: haloPaul 時間: 2018-12-22 19:01
本帖最後由 haloPaul 於 2018-12-22 19:03 編輯
唔該晒EITCo您呀,解釋得好詳細,而家明白左好多。
平常我最驚就係POINTER,感覺C語言真係博大精深。
但係我想問printf(""%s"\n"%s"\n"%s"\n\n", str_0, str_1, str_2);第二行在compiler編譯不到?
PS:我是用DEV C++
作者: EITCo 時間: 2018-12-22 20:40
差左啲escape啫
printf("\"%s\"\n\"%s\"\n\"%s\"\n\n", str_0, str_1, str_2);
我本來有打,被論壇個代碼排版功能過濾左
作者: java2 時間: 2018-12-24 10:39
本帖最後由 java2 於 2018-12-24 10:47 編輯
你學好C pointer 再問, 這是C 的基本功
作者: java2 時間: 2018-12-24 11:35
不要教新手在function 內malloc 又唔free 返, 咁好易搞出memory leakage.
最後如果要唔改動輸入的兩條strings,另造一條新的,就要用malloc
而上面第7至10行需要用兩次,所以寫個function (其實即係strcpy)
作者: little_keung 時間: 2018-12-24 13:00
其實 sample code 嚟, 唔少 C 書都有, 再唔係搵呢本 https://en.wikipedia.org/wiki/The_C_Programming_Language
或者去 glibc 睇下人地點寫.
https://github.com/lattera/glibc/blob/master/string/strcat.c
作者: cal22cal 時間: 2018-12-24 18:15
如果齋係搞 strcat,可以試吓咁:-
- char cCat[100];
- sprintf(cCat,"%s%s",dataA,dataB);
- printf("String after concatenation: %s\n", cCat);
作者: little_keung 時間: 2018-12-27 10:09
唔係話唔畀咁寫, 但係 sprintf 內部其實復雜過 strcat 好多.
如果係為咗練習 array 同 string operation , 又何需殺雞用牛刀??
strlen , strcat , strcpy 都係簡單到一個點.
作者: cal22cal 時間: 2018-12-27 10:34
唔係話唔畀咁寫, 但係 sprintf 內部其實復雜過 strcat 好多.
如果係為咗練習 array 同 string operation , 又何需殺雞用牛刀??
strlen , strcat , strcpy 都係簡單到一個點.
little_keung 發表於 2018-12-27 10:09
同意,當然係學習方向,解決問題有好多方法,一步步嚟。
作者: ray26342 時間: 2018-12-27 15:43
哈哈
見到個+號都打左個突