Из String (HEX) в unsigned long. Не вопрос!

krepton85
Offline
Зарегистрирован: 02.02.2016

Написал простую функцию преоброзования текстовых HEX значений объекта класса String в unsigned long, возможно каму то пригодится. Точно так же можно и из char * массива сделать, только добавить 2-ой аргумент длину строки.

unsigned long str_to_long(String str){
unsigned long ansver = 0;
  
for(byte n = 0; n < str.length(); n++){
 if((byte(str.charAt(n) ) >= 0x30) && (byte(str.charAt(n) ) <= 0x39)){//цифры ASCII 0 - 9
 ansver |= ((byte(str.charAt(n) )- 0x30));
 }
 if((byte(str.charAt(n) ) >= 0x41) && (byte(str.charAt(n) ) <= 0x46)){//символы ASCII A - F
 ansver |= ((byte(str.charAt(n) )- 0x41 + 10)); 
 }
 if((byte(str.charAt(n) ) >= 0x61) && (byte(str.charAt(n) ) <= 0x66)){//символы ASCII a - f
 ansver |= ((byte(str.charAt(n) )- 0x61 + 10)); 
 }
 
if(n < (str.length() - 1) ){
  ansver = ansver << 4;
}
  
}
 
 return ansver;
  
}

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

"Все уже украдено до нас!"

----------------------------------------------------

The strtol() function converts the string in nptrto a long value. The conversion is done according to the given base, which must be between 2 and 36 inclusive, or be the special value 0.

The string may begin with an arbitrary amount of white space (as determined by isspace()) followed by a single optional '+'or '-'sign. If baseis zero or 16, the string may then include a "0x"prefix, and the number will be read in base 16; otherwise, a zero base is taken as 10 (decimal) unless the next character is '0', in which case it is taken as 8 (octal).

The remainder of the string is converted to a long value in the obvious manner, stopping at the first character which is not a valid digit in the given base. (In bases above 10, the letter 'A'in either upper or lower case represents 10, 'B'represents 11, and so forth, with 'Z'representing 35.)

If endptris not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, however, strtol() stores the original value of nptrin endptr. (Thus, if *nptris not '\0'but **endptris '\0'on return, the entire string was valid.)

The strtol() function returns the result of the conversion, unless the value would underflow or overflow. If no conversion could be performed, 0 is returned. If an overflow or underflow occurs, errnois set to ERANGE and the function return value is clamped to LONG_MINor LONG_MAX, respectively.

long strtol ( const char *  __nptr,
    char **  __endptr,
    int  __base
  )    

=====================================

Не надо быть дебилом и смешить людей.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

wdrakula пишет:

Не надо быть дебилом и смешить людей.

Да, ладно Вам. Изобрести велосипед - гораздо лучше, чем ничего не изобрести.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

krepton85 пишет:

Написал простую функцию преоброзования текстовых HEX 

Вы это выложили "чтобы осчастливить человечество" или Вам нужен фидбэк для Вашей учёбы? Если второе, скажите, могу помочь.

Если первое, то, конечно, оно

krepton85 пишет:

возможно каму то пригодится

только вот, знаете, я честно потратил минут пять в попытках придумать менее эффективный и менее грамотный способ сделать это, чем тот, что использовали Вы. Не получилось. Наверное, квалификации не хватило, но придумать способ хуже, чем Ваш, я не сумел.

krepton85 пишет:

так же можно и из char * массива сделать, только добавить 2-ой аргумент длину строки.

Нафига? Число заканчивается либо первым символом - не имеющим право быть в числе, либо концом строки. Нафига там ещё длина?

 

krepton85
Offline
Зарегистрирован: 02.02.2016

Конечно выложил что бы осчасливить ардуинщиков. :)

Ну или так, без длины char массива.

unsigned long str_to_long(char *str){
unsigned long ansver = 0;
  
for(byte n = 0; n < sizeof(str); n++){
 if((byte(str.charAt(n) ) >= 0x30) && (byte(str.charAt(n) ) <= 0x39)){//цифры ASCII 0 - 9
 ansver |= ((byte(str.charAt(n) )- 0x30));
 }
else if((byte(str.charAt(n) ) >= 0x41) && (byte(str.charAt(n) ) <= 0x46)){//символы ASCII A - F
 ansver |= ((byte(str.charAt(n) )- 0x41 + 10)); 
 }
 else if((byte(str.charAt(n) ) >= 0x61) && (byte(str.charAt(n) ) <= 0x66)){//символы ASCII a - f
 ansver |= ((byte(str.charAt(n) )- 0x61 + 10)); 
 }
 else{
break;
}
  ansver = ansver << 4;

  
}
 
 return ansver;
  
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

krepton85 пишет:

Конечно выложил что бы осчасливить ардуинщиков. :)

Думаю, Вам удалось. По крайней мере, меня точно осчастливили.

krepton85 пишет:

Ну или так, без длины char массива.

unsigned long str_to_long(char *str){

Сами-то проверяли? Запустите с параметром "00FF" - посмотрите, что выдаст.

krepton85
Offline
Зарегистрирован: 02.02.2016

К сожалению последний код не проверял. Да там вообще лажа, не заметил.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так проверьте. И подумайте что делать вперёд: проверять или выкладывать. А то ведь Вам уже сказали в посте #1

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

krepton85 пишет:

Конечно выложил что бы осчасливить ардуинщиков. :)

Ну или так, без длины char массива.

unsigned long str_to_long(char *str){  
for(byte n = 0; n < sizeof(str); n++)

Херовое счастье, нерадостное какое-то. Оператор sizeof вернёт вам не длину строки, а размерность указателя. На некоторых платформах - это два байта, на некоторых - четыре, короче, it depends.  Но это - никак не длина строки.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Сие гениям неведомо