2016-12-10 2 views
0

Я пытаюсь разделить строку на две строки разделителем с этим кодомРазбивает строку на две строки по разделителю

int indexOf(char *msg, char c) { 
    int i; 
    for (i = 0; msg[i] != '\0'; i++) { 
     if (msg[i] == c) 
      return i; 
    } 
    return -1; 
} 

char *substring(char *msg, int startIndex, int endIndex) { 
    int length = endIndex - startIndex; 
    char *input = (char *)malloc(length * sizeof(char) + 1); 

    int i; 
    for (i = startIndex; i != endIndex; i++) { 
     input[i - startIndex] = msg[i]; 
    } 
    input[endIndex] = '\0'; 

    return input; 
} 

В main у меня есть:

index = indexOf(msg, ':'); 

first = substring(line, 0, index - 1); 
second = substring(line, index + 2, strlen(line)); 

Этот код производит правильный выход, когда я Test это с valgrind. Подстрока, выделенная во второй переменной, вызывает ошибку.

Где находится проблема? Есть ли другой способ разделить строку на две строки?

char *msg = readMessage(stdin); 
index = indexOf(msg, '\n'); 
char *line, *first, *second; 

line = substring(msg, 0, index); 

конец Valgrind Address 0x5203a52 is 5 bytes after a block of size 13 alloc'd

EDIT: Существует еще одна ошибка для

index = indexOf(line, ':'); 

Теперь ошибка Valgrind в подстроки в строке input[endIndex] = '\0';:

Invalid write of size 1 

EDIT: Решение моего кода, что есть две ошибки

в главном

index = indexOf(msg, ':'); 

должен быть

index = indexOf(line, ':'); 

и в подстроки

input[endIndex] = '\0'; 

должен быть

input[length] = '\0'; 

спасибо всем

+0

Какая ошибка? И, кстати, не бросайте 'malloc'. – coredump

+0

Вы также забрасываете 'malloc', если это не' strlen (msg) '? Куда входит «линия»? – t0mm13b

+0

может посмотреть в 'strtok'? Всегда инициализируйте переменные указателя на 'NULL' для здравомыслия. Вы отлаживали это? Что такое код для 'readMessage'? Я думаю, что переменная указателя, возвращаемая из функции, становится сбитой, поскольку она выделяется в стеке функции. – t0mm13b

ответ

1

Есть некоторые проблемы в вашем коде:

  • input[endIndex] = '\0'; использует неправильный индекс.Это должно быть input[length] = '\0';

  • в main(), вы не должны делать неявные предположения о возвращаемом значении indexOf. Опубликованный код вызывает неопределенное поведение, если : не найден в line:

Вот безопасный вариант:

int index = indexOf(line, ':'); 
if (index >= 0) { 
    // found the `:` separator 
    char *first = substring(line, 0, index); 
    if (line[index + 1] == ' ') { 
     index++; // skip the space after the : 
    } 
    char *second = substring(line, index + 1, strlen(line)); 
    ... 
} 

Вы можете использовать strcspn() вместо indexOf для извлечения деталей с меньшим количеством тестов:

char *msg = readMessage(stdin); 
size_t index = strcspn(msg, "\n"); 
char *line = substring(msg, 0, index); 
... 

strcspn() возвращает количество символов, но не включает d символов в строке аргумента. Он возвращает то же значение, что и indexOf(), если символ присутствует (за исключением типа size_t вместо int), и он возвращает длину строки, если это не так, что вам нужно в вашем случае.

+0

, проверьте, имеет ли строка ':' у меня в другом коде – mardon

+0

@mardon: 4386427 на самом деле заметила ошибку в вашем фрагменте из функции' main'. Он должен быть 'index = indexOf (строка, ':');' – chqrlie

1
index = indexOf(msg, ':'); 
       ^^^ 
       line ? 

Здесь

second = substring(line, index+2, strlen(line)); 

вы предполагаете, что эта строка длиннее, чем индекс + 2. Что-то, что вы должны проверить, чтобы избежать нуля в вызове malloc. Другими словами - если разделитель является последним символом, вы сталкиваетесь с проблемами.

Вы должны добавить проверку значения, возвращаемого malloc

if (!input) 
{ 
    // Print error message 
    exit(1); 
} 

BTW - посмотрите на strdup и memcpy или strncpy

+0

Пожалуйста, не защищайте использование 'strncpy'. https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/ – chqrlie

+0

@chqrlie - Проблема с завершением правильная. Я не уверен, что любая стандартная функция C решает это - вы знаете ее? Ваша ссылка решает его, написав пользовательскую функцию, использующую для C++. Выполняя то же самое в C, используя 'strncpy' – 4386427

Смежные вопросы