Thursday, February 18, 2010

OOP344 Challenge 2: myPrint function

The challenge can be found here.
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