Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странная работа оператора strtol
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Skaf
Всем привет. Пишу подпрограмму для конвертирования строки типа "00:1c:4f:a2:23:12" в 6 байт.

Использую функцию strtol

Код
unsigned long strtoul (const char * __nptr,  char ** __endptr,  int __base)


Судя по описанию __nptr указатель на строку, __endptr указатель на следующий символ после которого в строке не надо делать обработку, __base - система счисления строки

Долго боролся с глюками, в итоге соорудил маленький код в котором проявляется странное на мой взгляд поведение функции strtol. Объясните, пожалуйста, почему она модифицирует саму строку?

Строка- mac. Запись идет в data. Почему в mac изменяются 2 байта, а именно тот, на который указывает __endptr и следующий за ним? (код в картинке. Там же красным помечены изменившиеся байты из-за действий функции strtol)

PS- Последние 2 строки кода бессмыслены и существуют только для того, чтобы там поставить точку останова.
Xenia
Цитата(Skaf @ Oct 22 2010, 21:06) *
Всем привет. Пишу подпрограмму для конвертирования строки типа "00:1c:4f:a2:23:12" в 6 байт.
Судя по описанию __nptr указатель на строку, __endptr указатель на следующий символ после которого в строке не надо делать обработку, __base - система счисления строки
Долго боролся с глюками, в итоге соорудил маленький код в котором проявляется странное на мой взгляд поведение функции strtol. Объясните, пожалуйста, почему она модифицирует саму строку?

Нет, __endptr - это не указатель на следующий символ, а указатель на указатель! Оттого-то перед ним стоят две звездочки, а не одна.
Заведите себе ОТДЕЛЬНЫЙ указатель, назовите его хотя бы endptr, например так:
char *endptr;
А в функцию strtoul подставите его АДРЕС, например вот так:
rusult = long strtoul("00:1c:4f:a2:23:12", &endptr, 16);
Тогда фунция ПОЛОЖИТ в endptr указатель на следующий символ после конвертированного.
Следующие числа можно будет достать так:
rusult = long strtoul(endptr+1, &endptr, 16);
где 1 прибавляется для пропуска двоеточия.
Skaf
Исправил. Заработало. Странно, как же я проворонил там еще одну звездочку ))

Спасибо.

Вот получилась вот такая ПП

Код
void telnet_str2mac(char *str, unsigned char * data){
    char * ptr1, * ptr2;

    ptr1 = str;
    ptr2 = str;

    while(1){
        if (*ptr2 == 0x00) {
            *data = (unsigned char)strtol(ptr1, &ptr2, 16);
            data++;
            break;
        }
        if (*ptr2 != ':'){
            ptr2++;
        } else {
            *data = (unsigned char)strtol(ptr1, &ptr2, 16);
            data++;
            ptr2++;
            ptr1 = ptr2;
        }
    }
}


Получает на вход указатель на строку с MAC адресом и указатель на массив, куда можно записать данные. Вроде работает
rezident
Вы неправильно понимаете значение всех параметров этой функции. Почитайте ее описание, например, тут. Второй параметр функции это указатель на указатель, который служит для возврата значения указателя, который содержит адрес последнего непреобразованного символа в строке. Вместо того, чтобы передать адрес указателя, вы передаете в функцию его значение.
Измените строку
Код
*data=(unsigned char)strtol((const char *)ptr1, &ptr2, 16);


Опс! Тормознул с ответом. Уже ответили smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.