2014-10-28 54 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