현재 소형 마이크로 컨트롤러를 사용하여 코드를 작성하고 Sprintf 버전을 구현해야합니다 (표준 라이브러리 버전이 너무 큽니다). 나는 버전을 만들 수 있었지만 사람들이 어떤 개선점을 제안 할 수 있는지, 특히 조금 더 빨리 실행하거나 코드 크기를 줄이려면 어떤 제안을 할 수 있는지 궁금해했다.마이크로 용 Sprintf 개선
은 현재의 약자로 기능은 다음과 같습니다
int sprintf(char *s, const char *format, ...){
char c;
char i;
long n;
char length;
char *string;
va_list a;
va_start(a, format);
while (c = *format++) { //keep going untill the whole string is written to the array, increasing the pointer each loop round
if (c == '%') { //is the next character special
switch (c = *format++) { // move to the next postition to see what to do
case 's': // read a String from the corresponding variable
string = va_arg(a, char*);
i = 0;
while (string[i] != NULL) {
*s++ = string[i];
i++;
}
break;
case 'i': // read an integer from the corresponding variable
n = va_arg(a, int);
if (n > 100000) {
*s++ = IntToAcii(n/100000 % 10);
}
if (n > 10000) {
*s++ = IntToAcii(n/10000 % 10);
}
//Deliberately no break, rolls through to case below
case 'c': // read a char from the corresponding variable
if (c == 'c') {
n = va_arg(a, char);
}
if (n > 100) {
*s++ = IntToAcii(n/100 % 10);
}
if (n > 10) {
*s++ = IntToAcii(n/10 % 10);
}
*s++ = IntToAcii(n % 10);
break;
case '0': // inserts the number from the variable with padded 0 if it is too small to have a set size
length = *format++;
length -= 0x30;
switch (c = *format++) {
case 'i': // read an int from the corresponding variable (with padding)
n = va_arg(a, int);
if (length > 6) {
length = 6;
}
if (n > 100000) {
*s++ = IntToAcii(n/100000 % 10);
} else if (length >= 6) {
*s++ = '0';
}
if (n > 10000) {
*s++ = IntToAcii(n/10000 % 10);
} else if (length >= 5) {
*s++ = '0';
}
if (n > 1000) {
*s++ = IntToAcii(n/1000 % 10);
} else if (length >= 4) {
*s++ = '0';
}
//Deliberately no break, rolls through to case below
case 'c': // read a char from the corresponding variable (with padding)
if (c == 'c') {
if (length > 3) {
length = 3;
}
n = va_arg(a, char);
}
if (n > 100) {
*s++ = IntToAcii(n/100 % 10);
} else if (length >= 3) {
*s++ = '0';
}
if (n > 10) {
*s++ = IntToAcii(n/10 % 10);
} else if (length >= 2) {
*s++ = '0';
}
*s++ = IntToAcii(n % 10);
break;
}
break;
case 'p': // inserts the number from the variable with padded spaces if it is too small to have a set size
length = *format++;
length -= 0x30;
switch (c = *format++) {
case 'l': // read a long from the corresponding variable (with padding)
if (length > 9) {
length = 9;
}
n = va_arg(a, unsigned long);
if (n > 100000000) {
*s++ = IntToAcii(n/100000000 % 10);
} else if (length >= 9) {
*s++ = ' ';
}
if (n > 10000000) {
*s++ = IntToAcii(n/10000000 % 10);
} else if (length >= 8) {
*s++ = ' ';
}
if (n > 1000000) {
*s++ = IntToAcii(n/1000000 % 10);
} else if (length >= 7) {
*s++ = ' ';
}
//Deliberately no break, rolls through to case below
case 'i': // read an int from the corresponding variable (with padding)
if (c == 'i') {
if (length > 6) {
length = 6;
}
n = va_arg(a, int);
}
if (n > 100000) {
*s++ = IntToAcii(n/100000 % 10);
} else if (length >= 6) {
*s++ = ' ';
}
if (n > 10000) {
*s++ = IntToAcii(n/10000 % 10);
} else if (length >= 5) {
*s++ = ' ';
}
if (n > 1000) {
*s++ = IntToAcii(n/1000 % 10);
} else if (length >= 4) {
*s++ = ' ';
}
//Deliberately no break, rolls through to case below
case 'c': // read a char from the corresponding variable (with padding)
if (c == 'c') {
if (length > 3) {
length = 3;
}
n = va_arg(a, char);
}
if (n > 100) {
*s++ = IntToAcii(n/100 % 10);
} else if (length >= 3) {
*s++ = ' ';
}
if (n > 10) {
*s++ = IntToAcii(n/10 % 10);
} else if (length >= 2) {
*s++ = ' ';
}
*s++ = IntToAcii(n % 10);
break;
}
}
} else {
*s++ = c; //save the character from the string
}
}
return(1);
}
'% c'은 숫자가 아닌 단일 문자로 입력해야합니다. – StilesCrisis
'% s' 핸들러의 while (string [i]! = NULL)'은 혼란 스럽습니다. 'while (string [i]! = '\ 0')'이어야합니다. – unwind
@StilesCrisis 제 사용법 때문에 어떤 문자도 쓸 필요가 없지만 크기가 다른 (8,16,32 비트) 숫자를 보낼 수 있어야합니다. – Deamonata