HI
I want make a function similiar with printf;
code as follows:
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#ifdef _DEBUG
#define ASSERT(_expr) std::_assert((_expr) != 0, \
"ASSERT Failed, (" _STR(_expr) "), File: " __FILE__ \
", Line: " _STR(__LINE__) "\n")
#else
#define ASSERT(expr)
#endif/*DEBUG*/
typedef int BOOL;
typedef unsigned short WORD;
typedef unsigned long DWORD;
#define TRUE 1
#define FALSE 0
static const char * const g_pcHex = "0123456789abcdef";
char* StringWrite(char *pBuff,char* pCh,DWORD dwLen)
{
for(DWORD i=0;i<dwLen;i++) *pBuff++ = *pCh++;
*pBuff = 0;
return pBuff;
}
char* IntToASCII(char *pBuff,DWORD dwValue,BOOL bNeg,DWORD dwBase,DWORD dwCount,char cFill)
{
char pcBuf[16];
DWORD dwPos = 0;
DWORD i= 0;
// Determine the number of digits in the string version of the value.
for(i=1;(((i*dwBase)<=dwValue) && (((i*dwBase)/dwBase)==i));
i*=dwBase,dwCount--) {}
// If the value is negative, reduce the count of padding characters needed.
if(bNeg) dwCount--;
// If the value is negative and the value is padded with
// zeros, then place the minus sign before the padding.
if(bNeg && (cFill=='0'))
{
pcBuf[dwPos++] = '-';
bNeg = FALSE;
}
// Provide additional padding at the beginning of the string conversion if needed.
if((dwCount>1) && (dwCount<16))
{
for(dwCount--;dwCount;dwCount--) pcBuf[dwPos++] = cFill;
}
// If the value is negative, then place the minus sign before the number.
if(bNeg) pcBuf[dwPos++] = '-';
for(;i;i/=dwBase) // Convert the value into a string.
{
pcBuf[dwPos++] = g_pcHex[(dwValue / i) %dwBase];
}
return StringWrite(pBuff,pcBuf,dwPos);
}
char* FormatStr(char* pcBuff,char *pcString,...)
{
DWORD dwIdx,dwValue;
WORD wBase,wDigits/*指定输出位数*/;
BOOL bNeg,bDWORD;
char *pcStr,cFill,*pBuff;
va_list vaArgP;
ASSERT(pcBuff!=0); // Check the arguments.
ASSERT(pcString!=0); // Check the arguments.
va_start(vaArgP, pcString); // Start the varargs processing.
pBuff = pcBuff;
*pBuff = 0;
while(*pcString) // Loop while there are more characters in the string.
{
// Find the first non-% character, or the end of the string.
for(dwIdx=0;(pcString[dwIdx]!='%')&&(pcString[dwIdx]!='\0');dwIdx++) {}
pBuff = StringWrite(pBuff,pcString,dwIdx);
pcString += dwIdx; // Skip the portion of the string that was written.
if(*pcString=='%') // See if the next character is a %.
{
pcString++; // Skip the %.
wDigits = 0;
cFill = ' ';
while(*pcString>='0' && *pcString<='9')
{
if((*pcString=='0') && (wDigits==0)) cFill = '0';
wDigits *= 10; // Update the digit count.
wDigits += *pcString++ - '0';
}
if(*pcString=='l')
{
bDWORD = TRUE;
pcString++;
}
else bDWORD = FALSE;
switch(*pcString++)
{
case 'c': // Handle the %c command.
dwValue = va_arg(vaArgP,char);
pBuff = StringWrite(pBuff,(char*)&dwValue,1);
break;
case 'd': // Handle the %d command.
if(bDWORD) dwValue = va_arg(vaArgP,DWORD);
else dwValue = va_arg(vaArgP,WORD);
// If the value is negative, make it positive and indicate that a minus sign is needed.
if((long)dwValue<0)
{
dwValue = -(long)dwValue;
bNeg = TRUE;
}
else bNeg = FALSE;
wBase = 10; // Set the base to 10.
pBuff = IntToASCII(pBuff,dwValue,bNeg,wBase,wDigits,cFill);
break;
case 's': // Handle the %s command.
pcStr = va_arg(vaArgP, char*);
// Determine the length of the string.
for(dwIdx=0;pcStr[dwIdx]!='\0';dwIdx++) {}
pBuff = StringWrite(pBuff,pcStr,dwIdx);
// Write any required padding spaces
if(wDigits>dwIdx)
{
wDigits -= (WORD)dwIdx;
while(wDigits--) pBuff = StringWrite(pBuff," ", 1);
}
break;
case 'u': // Handle the %u command.
if(bDWORD) dwValue = va_arg(vaArgP,DWORD);
else dwValue = va_arg(vaArgP,WORD);
wBase = 10; // Set the base to 10.
// Indicate that the value is positive so that a minus sign
// isn't inserted.
bNeg = FALSE;
pBuff = IntToASCII(pBuff,dwValue,bNeg,wBase,wDigits,cFill);
break;
// Handle the %x and %X commands. Note that they are treated
// identically; i.e. %X will use lower case letters for a-f
// instead of the upper case letters is should use. We also
// alias %p to %x.
case 'x':
case 'X':
if(bDWORD) dwValue = va_arg(vaArgP,DWORD);
else dwValue = va_arg(vaArgP,WORD);
wBase = 16; // Set the base to 10.
// Indicate that the value is positive so that a minus sign
// isn't inserted.
bNeg = FALSE;
pBuff = IntToASCII(pBuff,dwValue,bNeg,wBase,wDigits,cFill);
break;
case 'p':
dwValue = (DWORD)va_arg(vaArgP,DWORD);
wBase = 16; // Set the base to 10.
// Indicate that the value is positive so that a minus sign
// isn't inserted.
bNeg = FALSE;
pBuff = IntToASCII(pBuff,dwValue,bNeg,wBase,wDigits,cFill);
break;
case '%': // Handle the %% command.
pBuff = StringWrite(pBuff,pcString-1,1); // Simply write a single %.
break;
default:
pBuff = StringWrite(pBuff,"ERROR",5);
break;
}
}
}
// End the varargs processing.
va_end(vaArgP);
return NULL;
}
Test code as follows:
char g_cString[500];
long* pP;
int main()
{
long i = 100;
pP = &i;
long* pb = &i;
FormatStr(g_cString,"jimmy is %ld",i);
}
The function seems running in right way, but all addrs of the the Temporary variables in function main changed.
why it happened? where is the problem?
thanks
jimmy