课上
lab1-exam
实现格式符%R
,并从va_list
中取得两个数a
,b
,输出一个区间(a, b)
。%
之后可以跟之前定义的格式符[flags][width][length]
,并将格式同时应用到两个数上。如果R
前[lengh]
为l
,则变量为long int
型,反之为int
型。
例:
printk("%8R", 2023, 2023)
标准输出
( 2023, 2023)
- 仿照
%d
的输出,注意输出两个整数,以及括号和连接符","。比较简单。
case 'R':
neg_flag = 0;
neg_flag2 = 0;
if (long_flag) {
num = va_arg(ap, long int);
num2 = va_arg(ap, long int);
} else {
num = va_arg(ap, int);
num2 = va_arg(ap, int);
}
out(data, "(", 1);
if (num < 0) {
num = -num;
neg_flag = 1;
}
if (num2 < 0) {
num2 = -num2;
neg_flag2 = 1;
}
print_num(out, data, num, 10, neg_flag, width, ladjust, padc, 0);
out(data, ",", 1);
print_num(out, data, num2, 10, neg_flag2, width, ladjust, padc, 0);
out(data, ")", 1);
break; //input
新定义的变量:
long num2;
int neg_flag2;
lab1-extra
实现sprintf
函数,将格式化字符串输出到指定的空间。
函数定义在include/string.h
中, 原型为:
int sprintf(char *buf, const char *fmt, ...);
参考printk
:
void printk(const char* fmt, ...);
void printk(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintfmt(outputk, NULL, fmt, ap);
va_end(ap);
}
实现sprintf
:
struct selfdef {
char *s;
int len;
};
int sprintf(char *buf, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
struct selfdef test;
test.s = buf;
test.len = 0;
vprintfmt(outputc, (void*)&test, fmt, ap);
va_end(ap);
int len = test.len;
return len;
}
此外还要定义类似outputk
的outputc
函数,这是一个回调函数,用于将得到的字符串输出到指定位置,注意记录位置,所以要传入结构体指针:
类比outputk
:
void outputk(void *data, const char *buf, size_t len) {
for (int i = 0; i < len; i++) {
printcharc(buf[i]);
}
}
可以发现我们必须获取buf
和当前出入在buf
的位置loc
,于是把他们们打包放进结构体selfdef
(代码在上面)。
实现outputc
:
void outputc(void *data, const char *buf, size_t len) {
struct selfdef* test = (struct selfdef *) data;
char *buff = test->s;
int loc = test->len;
for (int i = 0; i < len; i++) {
*(buff + i + loc) = buf[i];
}
test->len = loc + len;
*(buff + test->len) = '\0';
}
这次上机很顺利,离不开课程组的努力和老师助教的无私帮助,希望以后的上机会更好。