I have a problem with using increment ++ while trying to increase the value of an int variable. I'm passing the address of the variable called records to the function open() than opens a file in binary mode and then parses the file to find the amount of struct record elements present in the file. The problem is that when using the increment ++ as *records++;
the result is not what expected, for example I have 4 records in the .dat file and it prints:
HELLO! 1
HELLO! 0
HELLO! -251258176
HELLO! 22074
Back in main it prints:
Records in file: 0.
Now the weird thing is that instead of using increment ++, I use *records += 1;
, the result is as expected!
HELLO! 1
HELLO! 2
HELLO! 3
HELLO! 4
Back in main:
Records in file: 4.
I can't understand where is the issue. Part of code is included below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define true 1
#define false 0
#define size 100
typedef struct record {
char firstName[size], lastName[size];
int age;
double grade;
} record;
int open(const char *filename, FILE **fp, int *records);
int main() {
FILE *fp;
char filename[] = "records.dat";
int records = 0, opened = false, ch = 1;
while(ch > 0 && ch < 5) {
printf("Select your choice from the list below: \n");
printf("1. Open file and get amount of records in it\n");
printf("Enter your choice: ");
scanf("%d", &ch);
while(getchar() != '\n');
switch(ch) {
case 1:
if(opened) {
printf("\nFile already open, try closing it first please.\n");
break;
}
opened = open(filename, &fp, &records);
if(opened) {
printf("\nRecords in file: %d.\n", records);
} else { // Failed to open AND create file
return 1;
}
break;
default:
printf("\nGoodbye!\n");
if(opened) {
fclose(fp);
}
return 0;
break;
}
}
}
int open(const char *filename, FILE **fp, int *records) {
char temp[size];
record r;
*records = 0;
printf("Attempting to open file...\n");
*fp = fopen(filename, "rb+");
if(*fp == NULL) {
printf("File doesn't exit, attempting to create file...\n");
*fp = fopen(filename, "wb+");
if(*fp == NULL) {
fprintf(stderr, "Couldn't open neither create %s, exiting...\n", filename);
return false;
}
printf("File created.\n");
return true;
}
printf("File found!\n");
while(fread(&r, sizeof(r), 1, *fp) == 1) {
*records++;
//*records += 1;
printf("HELLO! %d\n", *records);
}
return true;
}
The ++
(increment) is binding more tightly than *
(dereference). Basically, what you're doing is changing the pointer, not the value. It's equivalent to:
*(records+=1);
Try (*records)++
instead to force the dereference to happen first.
But mostly, don't modify parameters like that -- instead make it a return value:
int open(...) {
int records=-1;
while( read ...) {
// do stuff
records++;
}
return records;
}
and use -1
to mean "error".
Or, if you must modify the parameter:
int open(..., int* records) {
int records_read = 0;
while( read ... ) {
// do stuff
records_read++;
}
*records = records_read;
return true;
}