【问题标题】:Setting width of text mentioned inside printf设置 printf 中提到的文本宽度
【发布时间】:2014-06-23 06:54:29
【问题描述】:

我在一些遗留调试文件中有一些代码,其中包含如下 printf 语句:

printf ("Abc1 = %d\n", var1);
printf ("Mnop2 = %d\n", var2);

这个文件有大约 100 个这样的 printf 语句。所有这些语句的文本(例如 Abc1)长度各不相同,输出看起来很丑。

我的问题是我可以以某种方式提及 ("") 中提到的文本字段的长度吗? 我知道我们可以添加一个 %s 并将文本移到外面。我不想这样做,因为这是遗留代码,而且我需要更改 100 个或更多 printfs。

感谢您的建议。

【问题讨论】:

  • 您的意思是希望数字从同一列开始吗?
  • @theunamedguy:是的,我想要 Abc1 = 123 之类的东西
  • 那我的回答应该有效

标签: c width printf


【解决方案1】:

左对齐:

int NumSpacesNeeded=32-strlen("Abc1 = ");
char buf[32];
memset(buf, 0, 32);
memset(buf, ' ', numSpacesNeeded);
printf("Abc1 = %s %d\n", buf, var1);

不过,这可能需要做很多工作。

【讨论】:

  • 感谢未命名的家伙。但是,我可以把“=”和数字一起带上吗?
  • 只需将标签放在'='前面
  • 如果数字超过制表符宽度,制表符字符看起来会一样难看(或者可以说更难看)。
  • 如果需要,您可以使用多个标签
  • @theunnamedguy:我试过了。但是,根据之前文本的长度, = %d 值不对齐。即,如果文本宽度超过一个制表符空间,则其值会将其移动到下一个制表符,使其未对齐
【解决方案2】:

如果我正确理解您的问题,您想在不“侵入”现有代码的情况下潜入幕后的整洁输出。

首先,将printf 替换为自定义名称。然后你可以在它周围写一个包装器。如果您的编译器理解可变参数宏,那么这可能只是一个宏。否则,您可以使用可变参数和vprintf 滚动您自己的类似printf 的函数。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#if VAR_ARG_MACRO_AVAILABLE

    #define tprintf(fmt, ...) do {          \
        printf("%.*s", 24 - strlen(fmt),    \
            "                        ");    \
        printf(fmt, __VA_ARGS__);           \
    } while (0)

#else

#include <stdarg.h>

int tprintf(const char *fmt, ...)
{
    va_list va;
    int n;

    va_start(va, fmt);

    n = 24 - strlen(fmt);
    if (n < 0) n = 0;
    printf("%.*s", n, "                        ");

    n += vprintf(fmt, va);

    va_end(va);

    return n;
}

#endif

int main()
{
    tprintf("a = %d\n", 2);
    tprintf("alpha = %d\n", 21);
    tprintf("alphabetical = %d\n", 112);

    return 0;
}

宏解决方案依赖于少于大约 20 个字符的变量名。否则,将采用字段宽度的绝对值,这可能会破坏您的布局。

使用strlen(而不是strchr(fmt, '='))是一个近似值,如果您有不同长度的格式说明符,例如%zu%llu 等等。

【讨论】:

  • 尝试了宏部分,它按预期工作。感谢您提供简单的解决方案。
【解决方案3】:

嗯,如果可以的话:

  1. 使用 %10d 通过变量添加填充,其中 10 是要填充的空格数。

  2. 使用\t 在“文本”后添加空格,但如果文本长度差异很大,则必须调整使用多少个 \t。

【讨论】:

  • 试过\t。文本宽度在 1 到 3 个制表符之间变化。所以,输出没有对齐。为了让我使用填充,我将不得不手动编辑 100 行......我只是想看看是否有一个简单的解决方案......
  • 哦,嗯,使用“= %d\n”作为搜索字符串进行搜索和替换?
  • @nitekrawler:对不起。我以为您在谈论填充文本并将文本移到“”之外。是的,我可以填充数字,但我想对齐 = 符号。
  • 我明白了,我认为@theunamedguy 最新的解决方案可能是填充文本的最佳方式。
【解决方案4】:

编辑使用重定向重新输出输出。

windows 示例如下:

#include <stdio.h>

#define OUTFILE "temp.txt"

#define START stream = freopen(OUTFILE, "w", stdout)
#define END reOUT()


FILE *stream;

void reOUT(void){
    stream = freopen("CON", "w", stdout);
    FILE *fin = fopen(OUTFILE, "r");
    char line[128], field1[16], field2[16];
    while(fgets(line, sizeof(line), fin)){
        if(sscanf(line, "%15s = %15s", field1, field2)==2)
            printf("%10s = %10s\n", field1, field2);
        else
            printf("%s", line);
    }
    fclose(fin);
    remove(OUTFILE);
}

int main(){
    int var1 = 11, var2=22;
    START;
    printf ("Abc1 = %d\n", var1);
    printf ("normal print\n");
    printf ("Mnop2 = %d\n", var2);
    END;
    return 0;
} 

【讨论】:

  • "/dev/tty" 而不是 Linux 的“CON”(我不测试)。或使用 dup 和 dup2。
猜你喜欢
  • 2011-10-29
  • 1970-01-01
  • 2022-01-06
  • 2012-10-26
  • 1970-01-01
  • 2022-08-18
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多