2012-01-23 8 views
2

То, что я хочу, чтобы моя программа заключалась в том, чтобы прочитать входной текст от пользователя, обозначить эту строку с пробелом, являющимся разделителем, и сохранить каждый токен в массиве char *, который затем возвращаться.Array of char * in C

вот фрагмент кода, который я пытаюсь заставить его работать правильно:

typedef char* String; 
String* split(char* cmd) 
{ 
    char* param; 
    char tmp[128]; 
    String* result = (String*) malloc(10*sizeof(String)); 
    memset(result,NULL,10); 

    strcpy(tmp,cmd); 

    param = strtok(tmp," "); 

    int index = 0; 
    while(param && index < sizeof(result)/sizeof(*result)) 
    { 

     result[index] = (char*) malloc(strlen(param)); 
     strcpy(result[index],param); 

     param = strtok(NULL," "); 
     index++; 
    } 

} 

Где ЦМД строку, я tokenizing и результат является массив, который будет содержать каждый маркер.

Этот фрагмент кода приводит к ошибкам при попытке перебрать возвращенного результата, используя простой цикл (возникает ошибка сегментации)

String* splittedCmd = split(command); 

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

В чем вопрос? – JAM

+2

Подумайте о локальных переменных и времени жизни. Подумайте о динамическом распределении, и почему у вас его нет. Подумайте об использовании 'strncpy' вместо этого. Подумайте о том, чтобы обозначить это как «домашнюю работу». И подумайте о переходе на C++. –

ответ

2

Здесь несколько вещей не так.

Прежде всего, вы возвращаете result, который представляет собой массив (но распадается на указатель на массив), который выделяется в стеке функции, поэтому он возвращается после возвращения функции. Вы должны динамически выделять массив (и полагаться на вызывающей free его):

String *result = malloc(10 * sizeof(String)); 

Кроме того, ваше состояние, чтобы остановить while цикл:

if(index == sizeof(result)) 

позволит цикл идти до index не 40 (если char* - 4 байта на вашей платформе), потому что sizeof возвращает размер операнда в байтах, а не элементы массива, поэтому sizeof(result) (опять же, зависит от платформы) 40. Это явно выходит за пределы массива.

Если вы еще используете локальный массив вместо malloc, вы могли бы изменить, что

if (index == sizeof(result)/sizeof(*result)) 

Однако, вы не можете сделать это сейчас, потому что result только указатель вместо массива и sizeof(result) будет всегда быть размером указателя на вашей платформе.

Вы можете просто удалить этот if полностью и изменить состояние while на

while (param && index < 10) 

Что гарантирует, что param не NULL, а также, что index меньше 10. Вы должны рассмотреть вопрос о внесении #define или const int или что-то для размера массива и использовать это вместо использования магического числа.

Кроме того, необходимо изменить

memset(result,NULL,10); 

в

memset(result,NULL, sizeof(String) * 10); 

Потому что если вы этого не сделаете, memset только установка первые 10 байтов памяти указал, что result 0, вместо всего, потому что он принимает число в байтах, а не в элементах массива.

+0

Я попытался выделить память, и я до сих пор не могу распечатать содержимое 'splittedCmd' – user1162954

+0

@ user1162954, разместив обновленный код. Не забывайте, что вам также нужно изменить свой цикл. –

+0

Я отправил обновленный код – user1162954

0

Вы не должны возвращать указатель на локальную переменную. После возврата функции split адрес памяти result может содержать мусор, поэтому при попытке распечатать его вы ссылаетесь на неверный указатель.

1

Просто подсказка - почему вы не пытаетесь использовать strtok? Это значительно упростило бы ситуацию.

+0

Он использует 'strtok' –

+0

Упс, неважно. Почему я получил поддержку? –

+0

Кто-то еще и не понял, что он использует его уже, я думаю :) –