2013-02-09 3 views
1

Приведенный ниже код должен взять данные из строки s и разбить их на данные двойного массива с пробелом в качестве разделителя. J счетчика неожиданно сбрасывает, когда он должен увеличить, чтобы завершить функциюСрочный счетчик сбрасывается неожиданно

полукокса * S, передается в функции

0.0000000E00  0.0000000E00  -1.9311798E+03  8.0321814E+02  8.0294336E+02 

диагностическая функция Printf ниже отпечатков:

0.000000 | 1 
0.000000 | 2 
-1931.179800 | 3 
803.218140 | 4 
802.943360 | 1 

It приводит к сбою программы

void split_data(char *s, double *data, int fields) { 
    char buff[DATA_MAX]; 
    int j = 0, i; 

    for(; *s; *s++) { 
    while(*s == ' ' || *s == '\t') /* trim leading white space */ 
     *s++; 

    i = 0; 
    while(!(*s == ' ' || *s == '\t')) 
     buff[i++] = *s++; 
    buff[i] = 0; 

    data[j++] = atof(buff); 
    printf("%lf | %d\n", data[j-1], j); 

    if(j == fields) 
     return; 
    } 
} 
+0

показать полную программу, как могут быть элементы в массиве данных, значение полей. выглядит как проблема с памятью. – rajneesh

ответ

0

Ваш цикл:

while(!(*s == ' ' || *s == '\t')) 
     buff[i++] = *s++; 

должен также содержать тест на конец строки s. Например, while(!(*s == ' ' || *s == '\t') && *s) ....

В противном случае buff будет по-прежнему заполняться «шумом» до тех пор, пока он не переполнится. И тогда другие переменные в стеке начнут сбиваться, например j. Но поведение очень зависит от компилятора.

+0

Я изменил его на while (! (* S == '' || * s == '\ t') && * s), и он сработал. Я не уверен, что это связано с переменным переменной j, хотя – user1588871

+0

Вы, вероятно, переполняете 'buff' шумом, а затем clobber' j'. –

+0

«Шум» - это случайные данные в памяти. Но часто эти «случайные» данные являются объектами zeros_, потому что по соображениям безопасности операционная система должна очистить любую память до ее передачи. Таким образом, 'j' перезаписывается нулями, и вы печатаете' j ++ 'как 1. (И MSVC в режиме отладки также устанавливает память на ноль.) –

0

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

Попробуйте увеличить DATA_MAX и посмотреть, не решена ли эта проблема.

0

Если fields больше, чем количество строк в вашем массиве символов, программа может потерпеть крах, так как ваше условие выхода основано только на сравнении j с fields. Можете ли вы попробовать со следующим изменением кода?

if((j == fields) || (*s == '\0')) 
    return; 
0

Проблема ваша вторая петля:

while(!(*s == ' ' || *s == '\t')) 
    buff[i++] = *s++; 
buff[i] = 0; 

Вы продолжаете заполнять буфер, если вы не достигнете «» из «\ г», к сожалению, строка окончания символа «\ 0» не является ни один из них, поэтому вы все равно продолжаете заполняться после достижения конца строки. В случае, если вам повезло, память, которую вы читаете, содержит любые «'' \ t ', и ваш цикл остановится, пока ваш буфер не будет заполнен.

Чтобы решить вашу проблему, вы также должны проверить '\ 0' в своем втором цикле - даже лучше, если вы сделаете это в первом (на случай, если для анализа не хватает значений) или добавьте дополнительный ' или '\ t' до конца строки.

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