Lyndon Cox
Lyndon Cox

Reputation: 50

C - sprintf() affecting array declaration

Firstly I'm new to C but not programming; I do a lot of web development in PHP. To the question...

I've got a function that reads a series of binary files and outputs the content, however the use of sprintf() is affecting the memory allocation for the multi-dimensional array that follows. See below:

FILE *fp;

for(int i = 1; i <= 16; i++) {

    char format_1[] = "track_%d.bin";
    char filename_1[sizeof format_1+100];
    sprintf(filename_1,format_1,i);
    printf("Filename: %s \n", filename_1);
    fp = fopen(filename_1, "rb");

    if(fp) {
        fseek(fp, 0L, SEEK_END);
        int sz = (ftell(fp) / 3) - 1;
        fseek(fp, 0L, SEEK_SET);

        printf("File size: %d\n", sz);

        int nums[sz][3];

        fread(nums,sizeof(int),sz * 3, fp);

        for (int k = 0; k < sz; k++) {
            printf("Entry number %d = %d with extra values of %d and %d\n", k, nums[k][0], nums[k][1], nums[k][2]);
        }
    } else {
        printf("Skipping \n");
    }

    fclose(fp);
}

I know it's the sprintf() causing the problem because I simplified the function to:

printf("Please enter file number... \n");
scanf("%d%c", &num_file, &term);

printf("Please enter how many instances in this file... \n");
scanf("%d%c", &num_instance, &term);

int nums[num_instance][3];

char format_1[] = "track_%d.bin";
char filename_1[sizeof format_1+3];
sprintf(filename_1,format_1,num_file);
printf("Filename: %s \n", filename_1);

fp = fopen(filename_1, "rb");

fread(nums,sizeof(int),num_instance * 3, fp);
fclose(fp);

for (int k = 0; k < num_notes; k++) {
    printf("Entry number %d = %d with extra values of %d and %d\n", k, nums[k][0], nums[k][1], nums[k][2]);
}

When I move the declaration of nums above the sprintf() it works fine (even if it's just above it) as soon as I move the declaration of nums below sprintf() the output looks like below:

Entry number: 0 = 71 with extra values 116 and 158
Entry number: 1 = -1073743712 with extra values -1073744240 and -1073744304
Entry number: 2 = -1073743896 with extra values 59983 and -1073744005

As you can see from the top code snippet, I need to have the declaration of nums below the sprintf() because I need to know the number of entries in the file.

Edit: I suppose it might help if I mention that a file contains a multi-dimensional array: array[x][3].

Really stumped on this one, any help is greatly appreciated.

Upvotes: 2

Views: 372

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126243

Your basic problem is that you're calculating the size of the file in bytes, and then trying to read that many integers from the file. Since integers are (on most machines) 4 bytes, this will fail, and you'll only read into the first quarter of your nums array. The rest will contain (and be printed as) random garbage, which is what you are seeing.

You should be checking the return value of fread to make sure it makes sense. If you change your code to

int numread = fread(nums,sizeof(int),sz * 3, fp);
printf("Read %d integers from file\n", numread);
for (int k = 0; k < sz; k++) {
    if (k < numread/3) {
        printf("Entry number %d = %d with extra values of %d and %d\n", k, nums[k][0], nums[k][1], nums[k][2]);
    } else {
        printf("Entry number %d doesn't exist in the file\n", k);
    }
}

you would see the problem immediately.

ALWAYS check your return values.

Upvotes: 2

Related Questions