addi II 0 26 мая, 2022 Опубликовано 26 мая, 2022 · Жалоба Здравствуйте ! Столкнулся с тем что в компиляторе не работает функция sscanf и sprintf(компилятор не популярный) Мне нужно форматировать хекс строку с разными байтными с полубайтными хекс символами и в uchar hex переменные Подскажите пожалуйста как можно это сделать так чтобы не городить большой огород Спасибо ! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 26 мая, 2022 Опубликовано 26 мая, 2022 · Жалоба Приветствую. Для начала, все-таки, постарайтесь внятнее сформулировать вопрос. А то какая-то каша. Вам что, нужна функция перевода hex-to-int? /* ch - ASCII-символ '0'...'9', 'a'('A')...'f'('F') */ static inline s32 hexToInt1(u32 ch) { if((ch -= '0') > 9) { ch &= ~0x20; if((ch -= 17) > 5) return -1; else ch += 10; } return ch; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 4 26 мая, 2022 Опубликовано 26 мая, 2022 · Жалоба Для преобразования в строку вот http://elm-chan.org/fsw/strf/xprintf.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 0 26 мая, 2022 Опубликовано 26 мая, 2022 (изменено) · Жалоба Спасибо за поддержку! У меня есть следующая строка принимаемая по юарту "#ААВСС\r" Где АА, хекс значение от 0 до FF B, хекс значение от 0 до F CC, хекс значение от 0 до FF Мне нужно эти три значения параметров парсировать и положить в 3 переменные типа unsigned char Сами строки я кладу по указателю для которого выделили маалоком соответствующий размер Также после /r я вставляю доп символ конца строки /0 И после этого применяю sscanf или sprintf Все данные принимаемые строк через указатель просматриваются Но после sscanf и sprintf ,в выходных переменных отформатированные значения получаются нулевыми И sscanf возвращает FF, а sprintf не нулевое, меньшее FF Выделяемую память пока нигде не удаляю Изменено 27 мая, 2022 пользователем addi II Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 26 мая, 2022 Опубликовано 26 мая, 2022 · Жалоба Пишиите на английском. Переводчик на русский очень плохо работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 26 мая, 2022 Опубликовано 26 мая, 2022 · Жалоба Вместо 10-15 строк в эпистолярном жанре Вы могли бы привести 3-4 сторки кода (даже одну), который "не идет" или работает не так, как Вы ожидали. В частности, соблюдаете ли Вы формат sscanf(" <указатель на входную строку для разбора>, <сторка/указатель на строку формата>", . . . "приемные" указатели . . . . ) - то что есть в документации на "базовый" С. (ошипку исправил) Quote И после этого применяю sscanf или sprintf совсем "одно и тоже". Это касаемо Вашего "или". Хотя-бы приведите строку формата, которую Вы используете в sscanf. Лучше полный код. Кроме того, в "недокомипляторах" может быть (сильно)урезанная версия работы с форматами в (s)printf, и уж тем более - в (s)scanf. Если есть возможность - отработайте Ваш код на нормальной платформе (Visual C любой самой древнй версии, Console32), добейтесь правильной работы, затем переносите на Ваш компилятор. ps чтобы sscanf правильно распарсил входную строку, в строке формата должен быть правильно закодирован терминирующий символ (\r) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 мая, 2022 Опубликовано 26 мая, 2022 · Жалоба 4 часа назад, addi II сказал: У меня есть следующая строка принимаемая по юарту "#ААВСС/r" Где АА, хекс значение от 0 до FF B, хекс значение от 0 до F CC, хекс значение от 0 до FF Мне нужно эти три значения параметров позвать и положить в 3 переменные unsigned char И зачем тут вообще sscanf и sprintf? Бред какой-то.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DX168B 0 26 мая, 2022 Опубликовано 26 мая, 2022 (изменено) · Жалоба Строка: A5 Из первого символа 'A' вычитаем 0x30. Если результат от 0 до 9, то так и используем. Если больше 9, то вычитаем 0x41. Если меньше 15, значит используем и в строке была большая буква А. Если больше 15, то вычитаем 0x61. Если результат меньше 15, то используем как есть и в строке была маленькая буква 'a'. Если больше 15, то введен неверный символ. Результат - это четыре бита. Куда их разместить, уже зависит от обрабатываемого символа. В нашем случае результат обработки символа "А" нужно сдвинуть на четыре бита влево, а результат обработки символа "5" сложить с предыдущим результатом посредством операции "ИЛИ". И так со всеми символами. Изменено 26 мая, 2022 пользователем DX168B Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 0 27 мая, 2022 Опубликовано 27 мая, 2022 (изменено) · Жалоба 14 hours ago, x893 said: Пишиите на английском. Переводчик на русский очень плохо работает. прошу прощения писал с телефона, исправил 13 hours ago, k155la3 said: Вместо 10-15 строк в эпистолярном жанре Вы могли бы привести 3-4 сторки кода (даже одну), который "не идет" или работает не так, как Вы ожидали. В частности, соблюдаете ли Вы формат sscanf(" <указатель на входную строку для разбора>, <сторка/указатель на строку формата>", . . . "приемные" указатели . . . . ) - то что есть в документации на "базовый" С. (ошипку исправил) совсем "одно и тоже". Это касаемо Вашего "или". Хотя-бы приведите строку формата, которую Вы используете в sscanf. Лучше полный код. Кроме того, в "недокомипляторах" может быть (сильно)урезанная версия работы с форматами в (s)printf, и уж тем более - в (s)scanf. Если есть возможность - отработайте Ваш код на нормальной платформе (Visual C любой самой древнй версии, Console32), добейтесь правильной работы, затем переносите на Ваш компилятор. ps чтобы sscanf правильно распарсил входную строку, в строке формата должен быть правильно закодирован терминирующий символ (\r) Спасибо большое, может быть в этом проблема, символ '\r' кодирую как 0x0D 10 hours ago, jcxz said: И зачем тут вообще sscanf и sprintf? Бред какой-то.... На мой взгляд не достаточно очевидно, как иначе, а с помощью sscanf/sprintf делать этого удобно Строку я сохраняю в память по указателю типа char, как по вашему они будут располагаться и как потом склеивать байтное значение и разделять полубайтное? 8 hours ago, DX168B said: Строка: A5 Из первого символа 'A' вычитаем 0x30. Если результат от 0 до 9, то так и используем. Если больше 9, то вычитаем 0x41. Если меньше 15, значит используем и в строке была большая буква А. Если больше 15, то вычитаем 0x61. Если результат меньше 15, то используем как есть и в строке была маленькая буква 'a'. Если больше 15, то введен неверный символ. Результат - это четыре бита. Куда их разместить, уже зависит от обрабатываемого символа. В нашем случае результат обработки символа "А" нужно сдвинуть на четыре бита влево, а результат обработки символа "5" сложить с предыдущим результатом посредством операции "ИЛИ". И так со всеми символами. Спасибо, поробую! Изменено 27 мая, 2022 пользователем addi II Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 0 27 мая, 2022 Опубликовано 27 мая, 2022 · Жалоба 14 hours ago, k155la3 said: Вместо 10-15 строк в эпистолярном жанре Вы могли бы привести 3-4 сторки кода (даже одну), который "не идет" или работает не так, как Вы ожидали. В частности, соблюдаете ли Вы формат sscanf(" <указатель на входную строку для разбора>, <сторка/указатель на строку формата>", . . . "приемные" указатели . . . . ) - то что есть в документации на "базовый" С. (ошипку исправил) совсем "одно и тоже". Это касаемо Вашего "или". Хотя-бы приведите строку формата, которую Вы используете в sscanf. Лучше полный код. Кроме того, в "недокомипляторах" может быть (сильно)урезанная версия работы с форматами в (s)printf, и уж тем более - в (s)scanf. Если есть возможность - отработайте Ваш код на нормальной платформе (Visual C любой самой древнй версии, Console32), добейтесь правильной работы, затем переносите на Ваш компилятор. ps чтобы sscanf правильно распарсил входную строку, в строке формата должен быть правильно закодирован терминирующий символ (\r) Вот код: #include "uart.h" #include <stdio.h> #include <stdlib.h> #include <string.h> volatile unsigned char temp=0; extern unsigned char ByteReceived; extern unsigned char status_uart ; volatile unsigned char sts=0; volatile unsigned char cntb=0; volatile unsigned char cmd=0; volatile unsigned char tr_s=0; volatile unsigned char i=0; volatile char* data1; volatile char* data2; volatile char cmd1[] = "!01-SPU-1000\r"; volatile char cmd2[] = "!02-SPU-1000\r"; volatile char reccmd1[] = "$01M\r"; volatile char error[] = "error\0"; volatile char reccmd2[] = "$02M\r"; volatile char toend[] = ">AA\r\0"; volatile unsigned char pref, aa,b,dd,n,d; volatile unsigned char debug=0; volatile unsigned char temp3; void main() { data1 = (char*)malloc(6 * sizeof(char)); data2 = (char*)malloc(17 * sizeof(char)); data3 = (char*)malloc(8 * sizeof(char)); ini(); while(1) { if(temp == 1) // when byte received { // парсинг этой строки работает if((ByteReceived == 0x24) && (sts ==0)) { // debug = 1; sts = 1; *(data1+ cntb) = ByteReceived; cntb++ ; ByteReceived = 0x00; temp = 0; } else { if((sts==1) && (ByteReceived == 0x0D)) { *(data1 + cntb) = ByteReceived;//'\r'; *(data1 + cntb + 1) = '\0'; ByteReceived = 0x00; temp = 0; if(strcmp((const char *)data1,(const char *) reccmd1) == 0 ) { adr = 0xC004; *(volatile short*)(adr) = 0xFF; IOPORT2 &= ~0x80; tr_s = sizeof(cmd1) - 1; i = 0; do { SBUF_TX0 = cmd1[i]; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); tr_s --; i++; } while(tr_s); sts = 0; cntb = 0; IOPORT2 |= 0x80; } else { if(strcmp((const char *)data1,(const char *) reccmd2) == 0 ) { IOPORT2 &= ~0x80; adr = 0xC004; *(volatile short*)(adr) = 0x55; tr_s = sizeof(cmd2) - 1; i = 0; do { SBUF_TX0 = cmd2[i];//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); tr_s --; i++; } while(tr_s); sts = 0; cntb = 0; } else { tr_s = sizeof(error) - 1; i = 0; do { SBUF_TX0 = error[i]; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); tr_s --; i++; } while(tr_s); sts = 0; cntb =0; IOPORT2 |= 0x80; } } } else { if((sts==1) && (ByteReceived != 0x0D)) { *(data1+ cntb) = ByteReceived; cntb++ ; temp = 0; } } } // прием строчки описанной в ветке, 0x230x300x310x310x310x320x0D if((ByteReceived == 0x23) && (sts == 0)) { cntb = 0; sts = 2; *(data2+ cntb) = ByteReceived; cntb++ ; ByteReceived = 0x00; temp = 0; } else { if((sts==2) && (ByteReceived == 0x0D)) { *(data2 + cntb) = ByteReceived ; *(data2 + cntb+1) = '\0'; ByteReceived = 0x00; temp = 0; temp3 = 0; // sscanf( (char*) data2, "%1u%2u%1u%2u",&pref, &aa, &b, &dd ); //temp3 = sscanf( (const char*) data2, "%1x%2x%1x%2x",&pref, &aa, &b, &dd ); temp3 = sprintf ( (char*) data2, "%1x%2x%1x%2x",(unsigned char)&pref, (unsigned char)&aa, (unsigned char)&b, (unsigned char)&dd ); //sscanf( (char*) data2, "#%2X%1X%2X", &aa, &b, &dd ); // sprintf (data2, "#%2X%1X%2X",&pref, &aa, &b, &dd ); ///sprintf (data2, "#%2X%1X%2X", &aa, &b, &dd ); //if(((data2[1]==0x30) && (data2[2]==0x31)) || ((data2[1]==0x30) && (data2[2]==0x32))) // if((aa== 0x00))// || (aa == 0x32)) //if((pref == 0x00) && (data2[0]==0x23) && (temp3 != 0x00)) //if((pref == 0x23) && (data2[0]==0x23)) //&& (temp3 != 0x00)) // if((aa== 0x31) || (aa == 0x32)) if((temp3 != 0x00) && (pref == 0x00)) { debug = 1; } cntb = 0; temp = 0; sts = 0; } else { if((sts==2) && (ByteReceived != 0x0D)) { *(data2+ cntb) = ByteReceived; cntb++ ; temp = 0; } } } } else { IOPORT2 |= 0x80; } if( ((debug==1) && (sts == 0)) )//|| ((debug==1) && (sts == 2)) ) { debug = 0; if(sts) sts =0; IOPORT2 &= ~0x80; SBUF_TX0 = pref+0x30;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); SBUF_TX0 = aa+0x30;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); SBUF_TX0 = b+0x30;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); SBUF_TX0 = dd+0x30;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); SBUF_TX0 = temp3 + 0x30;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); SBUF_TX0 = 0x24;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); SBUF_TX0 = 0x23;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); if(temp3 < 20) { SBUF_TX0 = 0x23;//ByteReceived;//0x01; do{status_uart = SP_STAT0;} while(!(status_uart & 0x08)); } } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 27 мая, 2022 Опубликовано 27 мая, 2022 (изменено) · Жалоба Может поможет: [url=https://github.com/eddyem/stm32samples/blob/master/F1:F103/MLX90640/strfunct.c#L187]ввод числа[/url]. Какой-то глюк с формой ответа: не могу url вставить нормально… В приведенном коде анализируется строка и преобразуется из десятичной, восьмеричной, двоичной или шестнадцатеричной записи. Изменено 27 мая, 2022 пользователем Eddy_Em Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 27 мая, 2022 Опубликовано 27 мая, 2022 · Жалоба 6 hours ago, addi II said: Вот код: . . . Да, с типом char в sscanf() есть некоторая неясность. А именно при "разборе" по формату "X"/HEX переменные (адреса) с типом (unsigned char) не воспринимаются корректно. Хотя n = sscanf() дает правильное кол-во принятых значений. И по указанным адресам что-то пишется. --- Меняем для sscanf/HEX рабочий тип переменных на unsigned (short) int. Если надо char переприсваиваем. // Win MS VStudio Console32 static unsigned int vcA, vcB, vcC, vcD; vcA = 0x11, vcB = 0x22, vcC = 0x33, vcD = 0x44; n = sscanf( ":AABCC-", ":%2x%1x%2x-", &vcA, &vcB, &vcC ); printf("\nn=%.2d", n); printf("\nA=%.02X", (unsigned int) vcA); printf("\nB=%.02X", (unsigned int) vcB); printf("\nC=%.02X", (unsigned int) vcC); printf("\n"); Очевидно, в sscanf() для "разбора" X/HEX формата есть ограничения (реализована только разрядность int и выше). Можно проверить, покурив документацию, а лучще - почитав исходник для sscanf(). ps Использовать sscanf() удобно там, где надо "разбирать" различную инф с различными форматами (возможно задаваемыми) динамически или через ini файл-данные. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 27 мая, 2022 Опубликовано 27 мая, 2022 · Жалоба 1 час назад, k155la3 сказал: Да, с типом char в sscanf() есть некоторая неясность. Во-первых, никакой неясности нет. char предназначен для хранения символов. Для чисел предназанчены (un)signed char Во-вторых, вы форматной строкой просите заносить результат в переменную типа unsigned int. Почему же вас удивляет, что компилятор делает именно то, что вы попросили? Для размещения в переменные другой размерности в форматной строке предусмотрены модификаторы l, h и ll, hh (начиная с C99). И напоследок: зачем вы в printf() делаете явное приведение к unsigned int переменной, которая и так имеет тип unsigned int? К тому же, при вызове функций с переменным числом аргументов используются integer promotion rules и все переменные, меньшие int, неявно приводятся к (un)signed int. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 27 мая, 2022 Опубликовано 27 мая, 2022 · Жалоба 1 hour ago, Сергей Борщ said: Во-первых, никакой неясности нет. Это само-собой. "Неясность" есть у меня. Но смысла разбираться мне с этим (модификаторами) сейчас нет. Это если у ТС будет непреодолимое желание "покурить взатяг". Попробовал модификатор hhx - не помогло. Смысла это вылавливать на компиляторе MSVS2008 нет, у ТС явно другое. Явное приведение для int в printf лишнее, согласен. Было явное приведение для char, не стал убирать, просто переправил для int. Явное для char нужно чтобы в printf не заморачиваться с модификаторами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 29 мая, 2022 Опубликовано 29 мая, 2022 (изменено) · Жалоба On 5/26/2022 at 2:51 PM, addi II said: Спасибо за поддержку! У меня есть следующая строка принимаемая по юарту "#ААВСС\r" Где АА, хекс значение от 0 до FF B, хекс значение от 0 до F CC, хекс значение от 0 до FF Мне нужно эти три значения параметров парсировать и положить в 3 переменные типа unsigned char я бы сделал так uint32_t HexStrToInt(char *hex) { uint32_t val = 0; while (*hex) { // get current character then increment uint8_t l_byte = *hex++; // transform hex character to the 4bit equivalent number, using the ascii table indexes if (l_byte >= '0' && l_byte <= '9') l_byte = l_byte - '0'; else if (l_byte >= 'a' && l_byte <='f') l_byte = l_byte - 'a' + 10; else if (l_byte >= 'A' && l_byte <='F') l_byte = l_byte - 'A' + 10; // shift 4 to make space for new digit, and add the 4 bits of the new digit val = (val << 4) | (l_byte & 0xF); } return val; } void Convert(char * str) { char tmp[3] = {0}; strncpy(tmp, &str[1], 2); unsigned char aa = HexStrToInt(tmp); strncpy(tmp, &str[3], 1); unsigned char bb = HexStrToInt(tmp); strncpy(tmp, &str[4], 2); unsigned char cc = HexStrToInt(tmp); } Изменено 29 мая, 2022 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться