c - 使用 printf 我使用的函数的输出返回错误的值

标签 c linux printf

我有这个代码:

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

char *K2G(int k)
{
    static char g[10];
    if (k > 1048576) {
        sprintf(g, "%.2fGB", (float) k / 1048576);
    } else {
        if (k > 1024) {
            sprintf(g, "%.2fMB", (float) k / 1024);
        } else {
            sprintf(g, "%dKB", k);
        }
    }
    printf("%s\n", g);
    return g;
}

main()
{
    FILE *fp;
    int imt = 0, imf = 0, imu = 0;
    char cmt[40], cmf[40], cmti[20], cmfi[20], a[20], b[20];
    while (1) {
        system("clear");
        fp = fopen("/proc/meminfo", "r");
        fgets(cmt, 40, fp);
        fgets(cmf, 40, fp);
        fclose(fp);
        printf("%s%s\n", cmf, cmt);
        sscanf(cmt, "%s%d%s", a, &imt, b);
        sscanf(cmf, "%s%d%s", a, &imf, b);
        imu = imt - imf;
        printf("%s/%s=%d%\n", K2G(imu), K2G(imt), imu * 100 / imt);
        sleep(1);
    }
}

我得到的输出是这样的:

MemFree:          494256 kB
MemTotal:       10258000 kB

9.78GB
9.31GB
9.31GB/9.31GB=95%

最后一行始终在等号前显示相同的两个值。输出应该是:

MemFree:          494724 kB
MemTotal:       10258000 kB

9.31GB
9.78GB
9.31GB/9.78GB=95%

为什么在使用 printf 调用函数 K2G 时会得到重复的值?这是给我错误结果的行:

printf("%s/%s=%d%\n", K2G(imu), K2G(imt), imu * 100 / imt);

最佳答案

这种行为是正常的,您返回一个指向 g 的指针,它是一个静态缓冲区,并且在每次调用时都会覆盖此缓冲区。

所以如果你执行 printf(..., K2G(x), K2G(Y),...),printf“看到”的参数将是相同的 g 缓冲区及其最新内容。

你可以这样做:

char simu[20];
char simt[20];
strcpy(simu, K2G(imu));
strcpy(simt, K2G(imt));
printf(..., simu, simt,...);

编辑:

或者您可以使用另一种模式,其中必须为 K2G 提供缓冲区:

char *K2G(int k, char *g)
{
    if (k > 1048576) {
        sprintf(g, "%.2fGB", (float) k / 1048576);
    } else {
        if (k > 1024) {
            sprintf(g, "%.2fMB", (float) k / 1024);
        } else {
            sprintf(g, "%dKB", k);
        }
    }
    printf("%s\n", g);
    return g;
}

...

char simu[20];
char simt[20];
K2G(imu, simu);
K2G(imt, simt);
printf(..., simu, simt,...);

这样更透明,避免了 strcpy 的使用。

关于c - 使用 printf 我使用的函数的输出返回错误的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33543280/

相关文章:

c - 在 C 中,如何将全局变量的范围限制在声明它的文件中?

c - 设置 Netbean 的默认值

linux - crontab 没有按计划时间运行

linux - 如何在 vi 中使用 wq~ 时删除在我的其他 linux 目录中意外创建的 ~

c - PAM:如何更改别人的密码?

C语言编程 printf

c - fopen 的路径存储在变量中

c - 问题访问 C 中字符指针数组的内容

c++ - 使用可变大小的参数 vector 格式化字符串(例如,将参数 vector 传递给 std::snprintf)

c - 从一个位置打印到另一个位置 - 使用 printf