2016-02-22 33 views
1

该C程序将字符串“1 2 3 4 5 6 7 8 9 10”分成标记,将它们存储在buf中,并打印buf的内容。为什么此C程序无法正常工作?

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

/* Fills an array with pointers to the tokens of the given string. 
* string: A null-terminated char* 
* buf: A buffer to be filled with pointers to each token. 
*/ 
void get_tokens(char * string, char ** buf) { 
    char tmp[100]; 
    strncpy(tmp, string, 100); 
    char * tok = strtok(tmp, " \n"); 
    int i = 0; 
    while (tok != NULL) { 
     buf[i] = tok; 
     tok = strtok(NULL, " \n"); 
     i++; 
    } 
} 

int main() { 
    char ** buf = malloc(10 * sizeof(char*)); 
    char * string = "1 2 3 4 5 6 7 8 9 10"; 
    get_tokens(string, buf); 

    int i; 
    for (i = 0; i < 10; i++) { 
     printf(" %s\n", buf[i]); 
    } 
} 

输出:

1 
    2 
    3 
    4 
    s�c8 
    �c8 
    8 

    9 
    10 

为什么我的输出被错位?

+4

的根本原因是'tmp'从'get_tokens'返回之后被淘汰的范围。 – Ctx

+0

'char tmp [100];'是局部变量。该部分地址超出范围无效。 – BLUEPIXY

+0

但是strtok返回的指针并不是指向tmp的指针,它们是由malloc – Jamie

回答

1

数组tmp是具有自动存储持续时间的本地函数数组。它在函数退出后被销毁。所以所有指向数组元素的指针都会失效。

我可以建议以下解决方案

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

size_t get_tokens(char ** buf, size_t n, const char *string) 
{ 
    char tmp[100]; 
    strncpy(tmp, string, 100); 
    tmp[99] = '\0'; 

    size_t i = 0; 
    char * tok = strtok(tmp, " "); 

    while (i < n && tok != NULL) 
    { 
     buf[i] = malloc(strlen(tok) + 1); 
     strcpy(buf[i++], tok); 
     tok = strtok(NULL, " "); 
    } 

    return i; 
} 

int main(void) 
{ 
    const size_t N = 10; 

    char ** buf = malloc(N * sizeof(char *)); 
    char * string = "1 2 3 4 5 6 7 8 9 10"; 

    size_t n = get_tokens(buf, N, string); 

    for (size_t i = 0; i < n; i++) 
    { 
     puts(buf[i]); 
    } 

    for (size_t i = 0; i < n; i++) free(buf[i]); 
    free(buf); 

    return 0; 
} 

程序输出是

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

至于你的程序那么至少你应该申报与存储说明符static阵列。

例如

static char tmp[100]; 
^^^^^^ 
strncpy(tmp, string, 100); 
tmp[99] = '\0'; 
^^^^^^^^^^^^^^^ 
相关问题