0

I have this code:

#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);
    }
}

The output I get is something like:

MemFree:          494256 kB
MemTotal:       10258000 kB

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

The last line always displays the same two values before the equal sign. The output should have been:

MemFree:          494724 kB
MemTotal:       10258000 kB

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

Why do I get duplicate values when I call function K2G with printf? This is the line giving me the incorrect results:

printf("%s/%s=%d%\n", K2G(imu), K2G(imt), imu * 100 / imt);
5
  • 1
    Please show us the code, the input values, and actual and expected output values. Edit your question to include that information. Without that information it's impossible to help you. Commented Nov 5, 2015 at 11:23
  • 1
    Please show your code in the question and not in a picture !! Commented Nov 5, 2015 at 11:28
  • 1
    Please, oh please, don't post images of text, especially links to those images. First of all, it's impossible to copy-paste text from images, second of all links can become stale which make the question useless. Commented Nov 5, 2015 at 11:28
  • 1
    And also please show input and expected and actual output. Commented Nov 5, 2015 at 11:30
  • Although Michael answered the question, a couple comments about your code. You should <string.h> and <unistd.h>. in this printf call printf("%s/%s=%d%\n", ... you should be using %% to print out a single % symbol. It should be "%s/%s=%d%%\n" and your main function should return an int. Declare it as int main() Commented Nov 5, 2015 at 12:23

1 Answer 1

2

This behaviour is normal, you return a pointer to g which is a static buffer, and on each call this buffer will be overwritten.

So if you do printf(..., K2G(x), K2G(Y),...), the parameters "seen" by printf will both be the same g buffer with it's latest content.

You can do this:

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

EDIT:

Or you can use another pattern where you have to provide a buffer to 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,...);

This is more transparent and avoids the usage of strcpy.

Sign up to request clarification or add additional context in comments.

3 Comments

@umläute: what possible advantage does strncpy (assumed) have over the suggested plain strcpy?
@jongware strncpy wouldn't be my first choice (it can still be abused), but strcpy is worse. Where available I usually use a version of BSD's strlcpy (usually you can find it as package libbsd on most distros). If you don't want to pull in a library strlcpy functionality can be replicated). In this case I think strncpy(simu, K2G(imu), sizeof(imu)-1); is reasonably safe as long as you don't use strncat.
@MichaelPetch: well I suggested strcpy because it's in the standard. Of course there are alternatives. But (see stackoverflow.com/a/2115072/2564301) problems arise when the programmer is not sure about the string lengths, and that does not appear to be the case here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.