📄 sprintf.c
字号:
/*
* File: sprintf.c
*/
#if !defined(__SPRINTF_H__)
#include "sprintf.h"
#endif
/*--------------------- Static Definitions ------------------------*/
enum PAD_ATTRIB {
PAD_NONE = 0,
PAD_RIGHT = 1,
PAD_ZERO = 2
};
// enough for 32-bit integer
#define PRINT_BUF_LEN 12 // 1_signed + 10_digit + 1_EOS
/*--------------------- Static Types ------------------------------*/
/*--------------------- Static Macros -----------------------------*/
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
/*--------------------- Static Functions --------------------------*/
static void s_vPrintChar(PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, CHAR c);
static INT s_iPrintStr(PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, PCSTR pszString, INT iWidth, UINT uPadAttr);
static INT s_iPrintInt(PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, INT iSgInt, INT iRadix, BOOL bSigned, INT iWidth, UINT uPadAttr, CHAR cDigitBase);
/*--------------------- Export Variables --------------------------*/
//
// if output string buffer is not null, then put char into buffer
// if buffer is null, then output to output device
//
static void s_vPrintChar (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, CHAR c)
{
if (ppszOutStr != NULL) {
**ppszOutStr = c;
++(*ppszOutStr);
}
else if (pfnOutput != NULL) {
pfnOutput(c);
}
}
static INT s_iPrintStr (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, PCSTR pszString, INT iWidth, UINT uPadAttr)
{
UINT uCharCount = 0;
UINT uPadLen = 0;
CHAR cPadChar = ' ';
if (iWidth > 0) {
INT iLen = 0;
PCCHAR pcChar;
// count string length
for (pcChar = pszString; *pcChar != '\0'; ++pcChar)
++iLen;
// calculate length to pad
if (iLen >= iWidth)
uPadLen = 0;
else
uPadLen = iWidth - iLen;
// decide pad space or zero
if (uPadAttr & PAD_ZERO)
cPadChar = '0';
}
// default is left padding, padding here
if (!(uPadAttr & PAD_RIGHT)) {
for (; uPadLen > 0; --uPadLen) {
s_vPrintChar(ppszOutStr, pfnOutput, cPadChar);
++uCharCount;
}
}
// just print the string
for (; *pszString != '\0' ; ++pszString) {
s_vPrintChar(ppszOutStr, pfnOutput, *pszString);
++uCharCount;
}
// if right padding, padding here
for (; uPadLen > 0; --uPadLen) {
s_vPrintChar(ppszOutStr, pfnOutput, cPadChar);
++uCharCount;
}
return uCharCount;
}
static INT s_iPrintInt (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, INT iSgInt, INT iRadix, BOOL bSigned, INT iWidth, UINT uPadAttr, CHAR cDigitBase)
{
CHAR aszPrintBuf[PRINT_BUF_LEN];
PCHAR pcResult;
INT iRemain;
UINT uPadCount = 0;
BOOL bNegative = FALSE;
UINT uUnsgInt = iSgInt;
if (iSgInt == 0) {
aszPrintBuf[0] = '0';
aszPrintBuf[1] = '\0';
return s_iPrintStr(ppszOutStr, pfnOutput, aszPrintBuf, iWidth, uPadAttr);
}
// check if negative or not
if (bSigned && (iRadix == 10) && (iSgInt < 0)) {
bNegative = TRUE;
uUnsgInt = -iSgInt;
}
// point to the end of the print buffer
pcResult = aszPrintBuf + PRINT_BUF_LEN - 1;
*pcResult = '\0';
while (uUnsgInt != 0) {
iRemain = uUnsgInt % iRadix;
if (iRemain >= 10)
iRemain += cDigitBase - '0' - 10;
--pcResult;
*pcResult = iRemain + '0';
uUnsgInt /= iRadix;
}
// if nagative, put minus sign
if (bNegative) {
if ((iWidth != 0) && (uPadAttr & PAD_ZERO)) {
s_vPrintChar(ppszOutStr, pfnOutput, '-');
++uPadCount;
--iWidth;
}
else {
--pcResult;
*pcResult = '-';
}
}
return uPadCount + s_iPrintStr(ppszOutStr, pfnOutput, pcResult, iWidth, uPadAttr);
}
INT PRNT_iPrintFmt (PSTR* ppszOutStr, PFN_HOOK_C pfnOutput, PINT piVarg)
{
INT iWidth;
UINT uPadAttr;
UINT uCharCount = 0;
PCHAR pcFormat = (PSTR)(*(piVarg++));
CHAR aszChar[2];
for (; *pcFormat != '\0'; ++pcFormat) {
if (*pcFormat == '%') {
++pcFormat;
iWidth = 0;
uPadAttr = PAD_NONE;
if (*pcFormat == '\0') {
break;
}
if (*pcFormat == '%') {
s_vPrintChar(ppszOutStr, pfnOutput, *pcFormat);
++uCharCount;
continue;
}
if (*pcFormat == '-') {
++pcFormat;
uPadAttr = PAD_RIGHT;
}
while (*pcFormat == '0') {
++pcFormat;
uPadAttr |= PAD_ZERO;
}
for (; ('0' <= *pcFormat) && (*pcFormat <= '9'); ++pcFormat) {
iWidth *= 10;
iWidth += *pcFormat - '0';
}
if (*pcFormat == 'c') {
aszChar[0] = *(piVarg++);
aszChar[1] = '\0';
uCharCount += s_iPrintStr(ppszOutStr, pfnOutput, aszChar, iWidth, uPadAttr);
continue;
}
if (*pcFormat == 's') {
PSTR pszStr = *((PSTR*)(piVarg++));
uCharCount += s_iPrintStr(ppszOutStr, pfnOutput, (pszStr != NULL) ? pszStr : "(null)", iWidth, uPadAttr);
continue;
}
if (*pcFormat == 'p') {
iWidth = 8;
uPadAttr |= PAD_ZERO;
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'a');
continue;
}
if (*pcFormat == 'x') {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'a');
continue;
}
if (*pcFormat == 'X') {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'A');
continue;
}
if (*pcFormat == 'u') {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, FALSE, iWidth, uPadAttr, 'a');
continue;
}
if ((*pcFormat == 'd') || (*pcFormat == 'i')) {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, TRUE, iWidth, uPadAttr, 'a');
continue;
}
if (*pcFormat == 'l') {
++pcFormat;
if (*pcFormat == 'x') {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'a');
continue;
}
if (*pcFormat == 'X') {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 16, FALSE, iWidth, uPadAttr, 'A');
continue;
}
if (*pcFormat == 'u') {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, FALSE, iWidth, uPadAttr, 'a');
continue;
}
if ((*pcFormat == 'd') || (*pcFormat == 'i')) {
uCharCount += s_iPrintInt(ppszOutStr, pfnOutput, *(piVarg++), 10, TRUE, iWidth, uPadAttr, 'a');
continue;
}
}
}
else {
s_vPrintChar(ppszOutStr, pfnOutput, *pcFormat);
++uCharCount;
}
}
// finally, put a zero at the end of string
if (ppszOutStr != NULL)
**ppszOutStr = '\0';
return uCharCount;
}
INT PRNT_iSprintf (PSTR pszBuffer, PCSTR pszFormat, ...)
{
PSTR piVarg = (PSTR)&pszFormat;
return PRNT_iPrintFmt(&pszBuffer, NULL, (PINT)piVarg);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -