sscanf, sprintf, stdio.h

Модераторы: ea, Alis, pip, gurzzza, _sva_

Ответить
addi
Сообщения: 19
Зарегистрирован: 29 сен 2021, 09:10
Предприятие: addico

sscanf, sprintf, stdio.h

Сообщение addi »

Здравствуйте!

Подскажите пожалуйста что может быть не так с использованием sscanf, sprintf, stdio.h

Попробовал использовать эти функции без включения stdio.h, все успешно компилировалось но с предупреждением что функции используется без прототипа
На практике они у меня не заработали
Если же включать в код stdio.h то возникает ошибка - "конфликт типов"

Вот код :

Код: Выделить всё

volatile char* data2;
volatile unsigned char pref=0, aa=0,b=0,dd=0,n=0,d=0;
data2 = (char*)malloc(8 * sizeof(char));
sscanf(  data2, "%1u%2u%1u%2u",&pref, &aa, &b, &dd );
if(((aa==0x01) || (aa==0x02)) && (pref == '#'))
{
	debug = 1;
}
Строки принимаю следующего содержания - "#AABСС/r"
где АА - HEX - символ от 00h до FFh
B – HEX - символ от 0 до F;
СС - HEX - символ от 00h до FFh
Также пробовал форматировать также через sprintf и также вместо u X формат, все бузуспешно

Прошу помочь разобраться

Спасибо!

П.С.
Микроконтроллер 1874ВЕ7Т
Codemaster-96
dav
Сообщения: 209
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: sscanf, sprintf, stdio.h

Сообщение dav »

addi писал(а): 15 май 2022, 20:26 Здравствуйте!
Подскажите пожалуйста что может быть не так с использованием sscanf, sprintf, stdio.h
Попробовал использовать эти функции без включения stdio.h, все успешно компилировалось но с предупреждением что функции используется без прототипа
На практике они у меня не заработали
Если же включать в код stdio.h то возникает ошибка - "конфликт типов"
Также пробовал форматировать также через sprintf и также вместо u X формат, все бузуспешно
Прошу помочь разобраться
Доброго времени суток!

1) Для правильной передачи параметров функции компилятор должен знать какую функцию мы вызываем, для этого и используется прототип функции. Прототипы функций для работы с вводом/выводом информации описаны в файле stdio.h. Также можно указать прототип только одной функции, например:

Код: Выделить всё

extern int    sprintf (char *,const char *, ...);
Если собрать проект без прототипа функции, то компилятор часть параметров передаст не через стек, а через рабочие регистры, что не будет соответствовать ожидаемым параметрам в теле функции. А в прототипе функции как раз и указано, каким образом передавать параметры при вызове функции. При несоответствии передаваемых параметров функции и получим неработающий код.

Дисассемблер вызова функции без объявления прототипа
; sprintf((char*)data2, "%1u%2u%1u%2u",(unsigned char)&pref, (unsigned char)&aa, (unsigned char)&bb, (unsigned char)&dd );
388B*C91502 PUSH #0215
388E C90902 PUSH #0209
3891 A30106021C LD AX,data2[00]
3896 A1D1381E LD BX,#38D1
389A A1170220 LD CX,#0217
389E A1080222 LD DX,#0208
38A2 EF1EF1 LCALL sprintf

Дисассемблер вызова функции с объявлением прототипа через #include <stdio.h>
; sprintf((char*)data2, "%1u%2u%1u%2u",(unsigned char)&pref, (unsigned char)&aa, (unsigned char)&bb, (unsigned char)&dd );
388D*C91502 PUSH #0215
3890 C90902 PUSH #0209
3893 C90802 PUSH #0208
3896 C91702 PUSH #0217
3899 C9D138 PUSH #38D1
389C A30106021C LD AX,data2[00]
38A1 EF1FF1 LCALL sprintf

2) Первым параметром функции sprintf(), sscanf() должен быть указатель на массив символов, в который функция sprintf() записывает форматированную строку, а функция sscanf() считывает. Поэтому, если массив символов объявлен как массив char data[10];, то вызов функций будет следующим:

Код: Выделить всё

char data[10];
volatile unsigned char aa,bb,cc;
void main()
{
sscanf(data, "%1u%2u%1u",&aa, &bb, &dd );
sprintf(data, "%X\n",aa);
}
Если же массив символов объявлен через указатель, то при вызове функции мы должны привести тип данных к (char*), и вызов функций будет следующим:

Код: Выделить всё

volatile char* data;
volatile unsigned char aa,bb,cc;
void main()
{
data = (char*)malloc(8 * sizeof(char));
sscanf((char*)data, "%1u%2u%1u",&aa, &bb, &dd );
sprintf((char*)data, "%X\n",aa);
}
addi
Сообщения: 19
Зарегистрирован: 29 сен 2021, 09:10
Предприятие: addico

Re: sscanf, sprintf, stdio.h

Сообщение addi »

Спасибо большое за развернутый ответ!

Я просто думал что прототип находиться как раз в sdio.h
Получается тогда мне нужно указывать в main прототип и включать sdio.h?

Но я не нашел на компьютере где стоит codemaster sdio.h
Подскажите пожалуйста где взять

Спасибо!
dav
Сообщения: 209
Зарегистрирован: 14 дек 2015, 09:21
Предприятие: АО НИИЭТ
Откуда: АО НИИЭТ, Воронеж

Re: sscanf, sprintf, stdio.h

Сообщение dav »

addi писал(а): 18 май 2022, 08:40 Я просто думал что прототип находиться как раз в sdio.h
Получается тогда мне нужно указывать в main прототип и включать sdio.h?
Можно либо указывать прототипы библиотечных в проекте, либо подключать заголовочный файл "stdio.h", в котором содержатся прототипы этих функций.
Ответить

Вернуться в «Микроконтроллеры семейства MCS-96»