2014-10-28 93 views
0

這是我的函數:分割字符串以140字符塊

char** split_string(char* message){ 

    int i = 0; 
    int j = 0; 
    int numberOfMsgs = 0; 
    int charsInLastMsg = (int)(strlen(message)%140); 


    if((int)strlen(message) > 140*4){ 
    return NULL; 
    } 

    if((int)(strlen(message)%140)){ 
    numberOfMsgs = (int)(strlen(message)/140) + 1; 
    } 
    else{ 
    numberOfMsgs = (int)(strlen(message)/140); 
    } 

    printf("message length = %d, we will have %d messages, and last msg will have %d characters\n", (int)strlen(message), numberOfMsgs, charsInLastMsg); 


    char **m = malloc(numberOfMsgs * sizeof(char*)); 
    for (j =0 ; j <= numberOfMsgs; j++){ 
    m[j] = malloc(141 * sizeof(char)); 
    } 

    for(i=0;i<numberOfMsgs;i++){ 
    if(i == numberOfMsgs - 1){ 

     memcpy(m[i], message + (140*i), charsInLastMsg); 
     m[i][charsInLastMsg] = '\0'; 
    } 
    else{ 
     memcpy(m[i], message + (140*i), 140); 
     m[i][140] = '\0'; 

    } 
    printf("m%d = %s\n", i, m[i]); 
    } 
    return m; 
} 

哪個我打電話是這樣的:

char* message = "1, 2, 3, 4, 5, 6, 7, 8, 9 and 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100."; 

int i=0; 
char** m = split_string(message); 
while(*m){ 
    printf("string%d = %s\n", i, m[i]);  //Problem at this line. 
    m++; 
} 

但是,當我運行它,我得到一個分段錯誤在上面指出的線上。如果我不打印,程序運行良好,所以我認爲split_string()函數是正常的。

我在做什麼錯?我是一個新手,plz的幫助。

/************************************預計O/P ***** *****************************/

我想將字符串分成140個字符串,如下所示:

string0 = 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 
string1 = , 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71 
string2 = , 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100. 
+2

你出去在數組邊界的'M' ..分配'米[J] = malloc的(140 *的sizeof(char)的)',然後嘗試'米[i] [140] ='\ 0';''m'從'0'到'139' – Haris 2014-10-28 11:11:26

+0

問題不在printf中,它是split_string函數不起作用的結果。順便說一句,你的預期產出是多少? – 2014-10-28 11:12:56

+0

感謝您指出緩衝區溢出。我編輯了這個問題。請看一下。 順便說一句,split_string()中的printf工作正常。 – Zaxter 2014-10-28 11:30:25

回答

1

這就是數組處理的問題,關於它的大小的信息應該存儲在某個地方,你永遠無法知道看到一個char **它有多少個成員。

這就是爲什麼存在以空字符結尾的字符串(c字符串)的原因,NULL char標記了它的結尾,因此您必須遍歷整個字符串,直到找到NULL以知道它的長度。

不管怎樣,我倒是建議你修改split_string()功能:

char** split_string(char* message, size_t * n_msgs) { 
    //... 
    *n_msgs = numberOfMsgs; 
    /// 
} 

然後:

size_t msgs = 0; 
char** m = split_string(message, &msgs); 
//... 
+0

感謝您的建議!好想法! – Zaxter 2014-10-28 12:12:39

1

你的while循環是一個無限循環。您正在測試從未更改的表達式*m,因此您將繼續增加i,並且最終m[i]將引用尚未分配的內存。

+0

我的錯誤,我編輯了這個問題。我++應該是m ++。 – Zaxter 2014-10-28 11:31:40

1

你應該改變
for (j =0 ; j <= numberOfMsgs; j++){ m[j] = malloc(141 * sizeof(char));

for (j =0 ; j < numberOfMsgs; j++){ 
m[j] = malloc(141 * sizeof(char)); 
+0

我剛試過。用valgrind跑。擺脫了一些無效的讀取。 但seg故障仍然存在。 – Zaxter 2014-10-28 11:42:54

+1

嘗試memmove而不是memcopy。 memcopy在重疊數組中有一些問題。只搜索memmove – 2014-10-28 11:51:13

+0

與memmove()相同的問題。 – Zaxter 2014-10-28 11:55:15

2

有一個重新編寫代碼中的幾個問題。你已經修復了一些。

你的客戶端代碼

while (*m) { 
    printf("string%d = %s\n", i, *m); 
    i++; 
    m++; 
} 

(其中我已經採取了自由與*m取代m[i]i總是0)表明,炭指針數組mNULL封端,即,一個NULL指針指示字符串列表的結尾。 (很像'\0'字符表示字符串的結束。)

但你的函數split_string不把NULL指針末端:您的客戶端代碼讀取超出有效的內存。

char **m = malloc(numberOfMsgs * sizeof(char*)); 

在這裏,你應該分配(numberOfMsgs + 1)串,一個額外的NULL

for (j =0 ; j <= numberOfMsgs; j++){ 
    m[j] = malloc(141 * sizeof(char)); 
} 

在這裏,你應該只分配numberOfMsgs字符串。該NULL字符串沒有進行分配,只是被設定爲NULL

m[numberOfMsgs] = NULL; 

最後,你應該釋放分配的內存。在你的情況下,你不能那樣做,因爲你已經增加(並因此改變了)基指針m。操作系統無法釋放內存,因爲新的m未由內存分配程序註冊。

所以,例如:

char **m = split_string(message, 140); 
int i = 0; 

while (m[i]) { 
    printf("%d: '%s'\n", i, m[i]); 
    free(m[i]); 
    i++; 
} 

free(m); 
+0

感謝您花時間寫這個答案。我正在進行建議的更改。 – Zaxter 2014-10-28 12:17:07