2016-03-02 2 views
-1

Я пытаюсь разобрать входную строку в команду и массив из аргументов строк.Ошибка семантизации: 11 при попытке разобрать строку

У меня возникла проблема с использованием strtok и strcpy, я думаю, что моя строка не имеет нулевого завершения, что приводит к ошибке seg.

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

#define delims " \t\r\n" 

int main() { 
    char input[] = "ls -a -f"; 
    char *buffer; 
    char command[256]; 
    char arguments[256][256]; 
    int i = 0, j; 

    buffer = strtok(input, delims); 

    strcpy(command, buffer); 

    printf("Command: %s\n\r", command); 

    while (buffer != NULL) 
    { 
     buffer = strtok(NULL, delims); 

     strcpy(arguments[++i], buffer); 
    } 

    buffer = strtok(NULL, delims); 

    for (j = 0; j < i; ++i) 
    { 
     printf("Argument[%d]: %s", j, arguments[j]); 
    } 

    return 0; 
} 

Выходной ток:

Command: ls 
Segmentation fault: 11 

Ожидаемый результат:

Command: ls 
Argument[0]: -a 
Argument[1]: -f 

Я не претендую быть очень хорошо с C, поэтому любые указатели в правильном направлении было бы чрезвычайно полезно ,

+0

Это не как структура цикла. Изменить while (buffer! = NULL) до while (strtok (NULL, delims)) – bruceg

+3

'strcpy (arguments [++ i], buffer);' - >> 'strcpy (arguments [i ++], buffer);' – wildplasser

+1

'while (buffer! = NULL) { buffer = strtok (NULL, delims); strcpy (аргументы [++ i], буфер); } buffer = strtok (NULL, delims); '->' while ((buffer = strtok (NULL, delims))! = NULL) {strcpy (arguments [i ++], buffer); } ' – BLUEPIXY

ответ

3

Ваша проблема, вероятно, вращается вокруг линии strcpy(arguments[++i], buffer);. Вы увеличиваете i и , затем используете его в качестве индекса массива. Первый раунд через цикл будет копироваться в индекс массива 1. Когда вы печатаете из цикла, вы начинаете с индекса 0. Поскольку вы не инициализируете массивы, они полны мусора, и плохие вещи возникают, когда вы пытаетесь распечатать индекс 0 (полный мусора) в виде строки.

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

1

следующий код:

  1. компилируется
  2. удаляют ненужные локальные переменные
  3. выходов соответствующих элементов, а затем завершает работу
  4. определяет магические числа со значимыми именами
  5. использует завершенный нуль массив для разделители для strtok()
  6. использовали «типичное» имя для возвращаемого значения strtok()
  7. всегда проверяет возвращаемое значение из strtok()

и теперь код:

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


#define MAX_CMD_LEN (256) 
#define MAX_ARGS (256) 
#define MAX_ARG_LEN (256) 

int main(void) 
{ 
    char input[] = "ls -a -f"; 
    char *token; 
    char command[ MAX_CMD_LEN ] = {'\0'}; 
    char arguments[ MAX_ARGS ][ MAX_ARG_LEN ] = {{'\0'}}; 

    if (NULL != (token = strtok(input, " \t\r\n"))) 
     strcpy(command, token); 

    printf("Command: %s\n\r", command); 

    size_t i = 0; 
    while (i<MAX_ARGS && NULL != (token = strtok(NULL, " \t\r\n"))) 
    { 
     strcpy(arguments[ i ], token); 
     i++; 
    } 


    for(i=0; *arguments[i]; i++) 
    { 
     printf("Argument[%lu]: %s\n", i, arguments[i]); 
    } 

    return 0; 
} // end function: main 
Смежные вопросы