2015-06-18 3 views
-1

я хочу, чтобы разбить строку в C с этим кодом:сегментации при использовании strtok_r

char *search = "+" ; 
char *temp1; 
char *temp2; 
char *saveptr1, *saveptr2 ; 
int operand1 ; 
int operand2 ; 
int result ; 
char sumBuff [5][25]  
temp1 = strtok_r(sumBuff[sumCounter-1], search, &saveptr1) ; 
operand2 = atoi(strtok_r(NULL, search, &saveptr1)); 
temp2 = strtok_r(temp1, ".", &saveptr2) ; 
operand1 = atoi(strtok_r(NULL, ".", &saveptr2)) ; 

, но когда я запускаю это в моем основном коде я получаю ошибку сегментации. и это результат трассировки стека:

#0 0x00007ffff7834517 in ??() from /lib/x86_64-linux-gnu/libc.so.6 
#1 0x00007ffff7830f60 in atoi() from /lib/x86_64-linux-gnu/libc.so.6 
#2 0x000000000040108c in plusExec (arg=0x0) at cm.c:112 
#3 0x00007ffff7bc4182 in start_thread() from /lib/x86_64-linux-gnu/libpthread.so.0 
#4 0x00007ffff78f147d in clone() from /lib/x86_64-linux-gnu/libc.so.6 

cm.112 является operand2 = atoi(...) Как я могу исправить эту ошибку?

+0

Ну, вы шаг через код и изучить переменные в отладчике? Это не полная программа, и вы показываете ссылки на переменные, которые не определены (sumCounter и т. Д.). – OldProgrammer

+3

Сбой в 'atoi()', который не любит получать 'NULL'. Вам нужно проверить, вернул ли 'strtok_r()' NULL'. – EOF

+0

@EOF Вы можете помочь мне больше? Что я должен делать в точности? – EmadSmart

ответ

2

Вы не проверяете возвращение strtok_r, что может быть NULL и, следовательно, авария atoi.

И в этом случае:

temp2 = strtok_r(temp1, ".", &saveptr2) ; 
operand1 = atoi(strtok_r(NULL, ".", &saveptr2)) ; 

... вы, кажется, ищет двух последовательных точек? Например, 5,123,723? Если есть только один, atoi получит NULL и coredump.

Если не должно быть двух последовательных «.», То это может быть ошибкой.

Предположив это не, попробуйте:

temp2 = strtok_r(temp1, ".", &saveptr2); // E.g. 5 

// If there is no other token, operand1 is set to zero. 
operand1 = 0; 
if (temp2 != NULL) { 
    char *temp3; 
    temp3 = strtok_r(NULL, ".", &saveptr2); // E.g. 123, or NULL 
    if (temp3 != NULL) { 
     operand1 = atoi(temp3); 
    } 
} 

(Тот же подход для первого atoi).

В зависимости от формата данных вы можете использовать функцию парсера, которая вернет массив целых чисел и его мощность; опять же, если вам придется иметь дело с переменно-пунктирными количествами, например, 192.168.1.1 или 1.2.7.0.80.17 - в противном случае вам не нужно беспокоиться:

/** 
* Parses a string in the format 1.2343.293.777 
* @param char * inputString  Input string 
* @param int * vect    Vector where to store integers 
* @param size_t n     Maximum vector size 
* @return size_t     Number of integers returned 
*/ 

size_t parseDottedIntegers(char *inputString, int *vect, size_t n) { 
    size_t i = 0; 
    char *p; 
    char *save = NULL; 
    p = strtok_r(inputString, ".", &save); 
    while (i < n) { 
     vect[i++] = atoi(p); 
     p = strtok_r(NULL, ".", &save); 
     if (NULL == p) { 
      return i; 
     } 
    } 
    // Error (e.g. too many parts) 
    return 0; 
} 
+1

Я склонен относиться с осторожностью к значениям нуля по умолчанию для подписанных типов. – EOF

+0

@lserni в 'sumBuff [sumCounter-1]' есть строка типа '123.456 + 789', которая' 123' - это номер строки, а '456' и' 789' - мои операнды1 и 2 – EmadSmart

+1

код, уже полученный 123. в первом вызове strtok_r(). поэтому следующие вызовы strtok_r() должны быть: 'temp3 = strtok_r (NULL, "+", & saveptr2);' – user3629249

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