繁体   English   中英

从自己的 printf function 获取宽度

[英]get the width from own printf function

我正在制作自己的 printf function。 但是,如果有超过 2 位数字,我无法从 va_arg 获取宽度。 例如在下面的代码中,我得到的宽度是23而不是123 请告诉我如何获得实际宽度,无论宽度中有多少数字。 除了使用指针*s,还有其他方法吗?

    char const *s = "%123s, hello";
    int i = 0;
    int width;
    
    while (s[i])
    {
        if(isdigit(s[i]) && isdigit(s[i + 1]))
            width = atoi(&s[i]);
        i++;
    }
    printf("%d", width);
    return 0;

//output = 23

当您找到123中的第一个数字时,您似乎可以跳出循环,以防止第二次调用atoi23

int width = 0;
int i = 0;
while(s[i]) {
    if (isdigit((unsigned char)s[i])) {
        width = atoi(s+i);
        break;
    }
    ++i;
}
printf("%d\n", width);

无论它是多少位数,您都需要解析长度。 使用strtol (返回数字后的字符)而不是atoi更容易做到这一点。 就像是

    while (s[i])
    {
        if(isdigit(s[i])) {
            char *end;
            width = strtol(&s[i], &end, 10);
            i = end - s;
        } else {
            // do something else with the format character
            i++;
        }
    }

如果不能使用libary strtol,就自己写吧; 这很简单:

long my_strtol(char *p, char **end) {
    // hardcoded base 10 and positive
    long rv = 0;
    while (isdigit(*p)) {
        rv = rv * 10 + *p - '0';
        ++p; }
    *end = p;
    return rv;
}

OP 的代码在while循环中反复尝试atoi() 只需要一次转换。

然而,由于"%s"可能具有atoi()使用'0''+''-'' '标志,因此最好使用替代代码进行处理。

char const *s = "%123s, hello";

char *flag = s;
while (*s && strchr("-+ #0", *s)) {
  s++;
}
char *last_flag = s;

// Determine the minimum width
int width = 0;
while (isdigit(*(unsigned char *)s)) {
  width = width * 10 + (*s - '0');
  s++;
}

// Determine the precision
int precision = DEFAULT;
if (*s == '.') { 
  s++;
  precision = 0;
  while (isdigit(*(unsigned char *)s)) {
    precision = precision * 10 + (*s - '0');
    s++;
  }
}

// Missing step, look for modifiers h,hh,l,ll,j,z,t,L

printf("f: %.*s\n", (int)(last_flag - flag), flag);
printf("w: %d\n", width);
printf("p: %d\n", precision);
printf("Rest of format: <%s>\n", s);

更多迂腐的代码会注意width * 10 + (*s - '0')的溢出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM