Below is my solution.
#include "biof.h"
#include "<"string.h">"
#include "<"stdio.h>"
#include "<"stdarg.h>"
#include "<"stdlib.h>"
char* toUpperCase(char* str){
int i = 0;
for(i = 0; i < strlen(str); i++)
if(str[i] >= 'a' && str[i] <= 'z')
str[i] -= 32;
return str;
}
char* myItoa(int val, char* str){
int i;
int j;
int length;
int scale;
if (val == 0){
str[0] = '0';
str[1] = '\0';
}
else{
for (i = 1, length = 0; val / i != 0 ; i *= 10, length++);
if (val > 0) {
for (i = 0; i < length; i++){
scale = 1;
for (j = 0; length - j > i + 1; j++)
scale *= 10;
str[i] = (val / scale) % 10 + 48;
}
str[i] = '\0';
}
else {
val *= -1;
str[0] = '-';
for (i = 0; i < length; i++){
scale = 1;
for (j = 0; length - j > i + 1; j++)
scale *= 10;
str[i+1] = (val / scale) % 10 + 48;
}
str[i+1] = '\0';
}
}
return str;
}
char* myFtoa(double val, char* str){
int decPart = ((int)(val * 100)) % 100;
int intPart = (int)val;
int roundPos = ((int)(val * 1000)) % 10;
char dot[2] = ".";
char decStr[3] = "";
char intStr[20] = "";
if(roundPos >=5)
decPart++;
myItoa(decPart, decStr);
myItoa(intPart, intStr);
strcpy(str,"");
strcat(str, intStr);
strcat(str, dot);
strcat(str, decStr);
return str;
}
void bio_putint(int val){
char temp[20] = "";
bio_putstr(myItoa(val, temp));
}
int myPrint(const char* msg, ...){
int i = 0;
int num = 0;
char buf[100];
int dTemp;
int hTemp;
double fTemp;
char cTemp;
const char* strTemp;
va_list args;
va_start(args, msg);
for(i = 0; i < strlen(msg); i++)
if(msg[i] == '%' &&
(msg[i+1]=='b' || msg[i+1]=='c' || msg[i+1]=='f' ||
msg[i+1]=='s' || msg[i+1]=='x' || msg[i+1]=='X') )
num++;
for(i = 0; i < strlen(msg); i++){
if(msg[i] != '%')
bio_putch(msg[i]);
else if(msg[i] == '%'){
buf[0] = 0;
switch(msg[i+1]){
case 'd': dTemp = va_arg(args, int);
bio_putint(dTemp);
i++;
break;
case 'c': cTemp = va_arg(args, char);
bio_putch(cTemp);
i++;
break;
case 'x': hTemp = va_arg(args, int);
itoa(hTemp, buf, 16);
bio_putstr(buf);
i++;
break;
case 'X': hTemp = va_arg(args, int);
itoa(hTemp, buf, 16);
bio_putstr(toUpperCase(buf));
i++;
break;
case 'f': fTemp = va_arg(args, double);
bio_putstr(myFtoa(fTemp, buf));
i++;
break;
case 's': strTemp = va_arg(args, const char*);
bio_putstr(strTemp);
i++;
break;
default:
bio_putch(msg[i]);
break;
}
}
}
va_end(args);
return num;
}
int main(){
int howMany;
bio_init();
howMany = myPrint("int %d, char %c, string %s, hex %X, float %f.\n", -56, 'M', "OOP344", 12, 12.34567);
myPrint("Printed %d parameter(s)", howMany);
bio_getch();
bio_end();
return 0;
}
Tested under VCC and BCC.
output is:
int -56, char M, string OOP344, hex C, float 12.35.
Printed 5 parameter(s)
I add a logical control that can round the decimal value. For example: 3.675 will be printed 3.68, while 5.321 will be printed 5.32.
No comments:
Post a Comment