BUAA_OS_LAB 1 内核 启动 printf


实验报告链接:

课上

lab1-exam

实现格式符%R,并从va_list中取得两个数ab,输出一个区间(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;
}

此外还要定义类似outputkoutputc函数,这是一个回调函数,用于将得到的字符串输出到指定位置,注意记录位置,所以要传入结构体指针:

类比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';
}

这次上机很顺利,离不开课程组的努力和老师助教的无私帮助,希望以后的上机会更好。


Author: Yixiang Zhang
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Yixiang Zhang !
评论
  TOC