2015-02-19 1 views
1

Мне нужно преобразовать большое число символов в длинный, чтобы запрограммировать чип Atmega8 на AtmelStudio.Ошибка C strtoul() для больших значений в AtmelStudio

Я пробовал использовать atol() и strtoul(), и он не работает. Я читал в google, что есть ошибка с strtoul(), которая позволяет использовать только меньшие значения. Я попробовал, и это правда. Я могу преобразовать char «250» в длинный с strtoul(), но не «5555».

Я читал, что исправление заключается в создании вашей собственной функции strtoul(), но как мне это сделать? Я не знаю реализации strtoul(), это внешний вид в библиотеке.

Это не работает:

char *my_time = "2505";  
unsigned long new2 = (unsigned)strtoul(my_time, NULL, 10); 
+0

@JoachimPileborg Я не знаю, я делаю встроенное программирование, у меня нет printf. Из того, что я вижу, похоже, что он возвращает 0. –

+0

Итак, в чем вопрос, пожалуйста? – alk

+0

Итак, чтобы уточнить, вы говорите, что эти функции ошибочны в вашей реализации * библиотеки C, да? –

ответ

2

Ядро преобразования (без знака) десятичную строку в целое число является:

unsigned long str2int(const char *s) 
{ 
    unsigned long x = 0; 
    while(isdigit(*s)) 
    { 
    x *= 10; 
    x += *s++ - '0'; 
    } 
    return x; 
} 

Это действительно не очень сложно, он просто просматривает цифры, создавая ценность по мере ее появления. *s++ - '0', пожалуй, является признаком того, что я не смог обуздать мой «сильный синдром синдрома« опытного программиста C ». Также я был в спешке. Более четкий подход может быть:

while(isdigit(*s)) 
{ 
    x *= 10; /* Each new digit makes the old ones worth more. */ 
    const int digit = *s - '0'; /* Convert digit character to small int. */ 
    x += digit; /* Add the current digit. */ 
    ++s; 
} 

Так, например, рассмотрим ввод "432". Он будет вычисляться как нечто вроде ((0 * 10 + 4) * 10 + 3) * 10 + 2.

Поскольку вы работаете с 8-разрядным микроконтроллером, возможно, вы получите много кодового пространства ограничивая себя uint16_t вместо unsigned long, если ваше приложение ограничено целыми числами ниже 65,536.

+0

Я не понимаю - «0» –

+0

Зонный ответ на вопрос во встроенном пространстве! –

+0

@ConradC Преобразует цифру (символ) в маленькое целое число. ''0' '- это цифра (символ, символ, символ), которая представляет целое число« 0 », поэтому путем вычитания« 0 »из известного символа цифры мы получаем целочисленное представление. C гарантирует, что цифровые символы закодированы таким образом, чтобы это работало. – unwind

0

Пожалуйста, запустите эту программу испытаний и сказать нам, что он печатает. Если у вас нет printf, найдите в некотором роде, чтобы получить нам ту же информацию, что и эта программа. (Если у вас нет errno, что часть не так важна, как и все остальное.)

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

int main(void) 
{ 
    const char *my_time = "2505"; 
    char *endptr; 
    unsigned long value; 

    errno = 0; 
    value = strtoul(my_time, &endptr, 10); 
    printf("value=%lu endptr=%s delta=%ld errno=%d (%s)\n", 
      value, endptr, (long)(endptr - my_time), 
      errno, strerror(errno)); 
    return 0; 
} 
+0

Ошибка undefined ссылка на 'strerror ' Я не думаю, что смогу« распечатать »на AtmelStudio. Это встроенное программирование –

+1

Если у вас нет 'strerror', просто возьмите эту часть. – zwol

0

Преобразование строки десятичных цифр, представляющих число в диапазоне от unsigned long, до unsigned long. Например:

unsigned long my_atoul(const char *digits) { 
    unsigned long result = 0; 
    const char *c = digits; 

    while ('0' <= *c && *c <= '9') { 
     result = result * 10 + (*(c++) - '0'); 
    } 

    return result; 
} 

Если вы хотите дополнительных свойств (например, выбор из радикса) или различное поведение на нечисловом или избыточную длину ввода, то такие вещи могут быть реализованы на вершине этого базового подхода.