Fwrite a dynamic structure passed by reference
Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:
void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);
while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;
if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}
And that is how I call this function from main:
FILE* db = NULL;
int choice = 0;
db = openDatabase(db);
Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}
Memory allocation to the structure happens in a different function.
If structure was local, in fwrite as 1st parameter I would write
&carPtr[number-1]
But in my case this does not work.
Car declaration:
struct car
{
char make[15];
char model[15];
int year;
double price;
};
c
add a comment |
Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:
void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);
while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;
if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}
And that is how I call this function from main:
FILE* db = NULL;
int choice = 0;
db = openDatabase(db);
Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}
Memory allocation to the structure happens in a different function.
If structure was local, in fwrite as 1st parameter I would write
&carPtr[number-1]
But in my case this does not work.
Car declaration:
struct car
{
char make[15];
char model[15];
int year;
double price;
};
c
How isCar
declared?
– Kamil Cuk
Nov 25 '18 at 20:53
1
Edited my question to include it
– Arkadijus
Nov 25 '18 at 20:57
I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used inloadData()
only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointercr
and use use it to pint to the data.
– Frankie_C
Nov 25 '18 at 21:04
I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.
– Arkadijus
Nov 25 '18 at 21:20
To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..
– too honest for this site
Nov 25 '18 at 21:22
add a comment |
Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:
void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);
while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;
if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}
And that is how I call this function from main:
FILE* db = NULL;
int choice = 0;
db = openDatabase(db);
Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}
Memory allocation to the structure happens in a different function.
If structure was local, in fwrite as 1st parameter I would write
&carPtr[number-1]
But in my case this does not work.
Car declaration:
struct car
{
char make[15];
char model[15];
int year;
double price;
};
c
Not sure if my title makes much sense, but what I am trying to do is fwrite from dynamic structure to file, but what makes this somewhat harder is that my structure is passed by reference and I do not know how 1st parameter of fwrite should look like. Here is a part of the code:
void editData(FILE* fPtr, Car* carPtr, int* size)
{
int number = 0;
printData(carPtr, size);
while(1)
{
if ((scanf("%d", &number) == 1) && (getchar() == 'n'))
{
if ((number > 0) && (number <= *size))
{
char make[15] = "", model[15] = "";
int year = 0;
double price = 0;
if (getUserInput(make, model, &year, &price) == 1)
{
strcpy((*carPtr+number-1)->make, make);
strcpy((*carPtr+number-1)->model, model);
(*carPtr+number-1)->year = year;
(*carPtr+number-1)->price = price;
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
fwrite(**&carPtr[number-1]**, sizeof(Car), 1, fPtr);
}
And that is how I call this function from main:
FILE* db = NULL;
int choice = 0;
db = openDatabase(db);
Car* cr = NULL;
int size = 0;
loadData(db, &cr, &size);
while((choice = menuChoice()) != 5)
{
switch (choice)
{
case 1:
insertData(db, &cr, &size);
break;
case 2:
**editData(db, &cr, &size);**
break;
case 4:
printData(&cr, &size);
break;
}
}
free(cr);
fclose(db);
}
Memory allocation to the structure happens in a different function.
If structure was local, in fwrite as 1st parameter I would write
&carPtr[number-1]
But in my case this does not work.
Car declaration:
struct car
{
char make[15];
char model[15];
int year;
double price;
};
c
c
edited Nov 25 '18 at 20:55
Arkadijus
asked Nov 25 '18 at 20:47
ArkadijusArkadijus
145
145
How isCar
declared?
– Kamil Cuk
Nov 25 '18 at 20:53
1
Edited my question to include it
– Arkadijus
Nov 25 '18 at 20:57
I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used inloadData()
only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointercr
and use use it to pint to the data.
– Frankie_C
Nov 25 '18 at 21:04
I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.
– Arkadijus
Nov 25 '18 at 21:20
To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..
– too honest for this site
Nov 25 '18 at 21:22
add a comment |
How isCar
declared?
– Kamil Cuk
Nov 25 '18 at 20:53
1
Edited my question to include it
– Arkadijus
Nov 25 '18 at 20:57
I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used inloadData()
only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointercr
and use use it to pint to the data.
– Frankie_C
Nov 25 '18 at 21:04
I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.
– Arkadijus
Nov 25 '18 at 21:20
To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..
– too honest for this site
Nov 25 '18 at 21:22
How is
Car
declared?– Kamil Cuk
Nov 25 '18 at 20:53
How is
Car
declared?– Kamil Cuk
Nov 25 '18 at 20:53
1
1
Edited my question to include it
– Arkadijus
Nov 25 '18 at 20:57
Edited my question to include it
– Arkadijus
Nov 25 '18 at 20:57
I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in
loadData()
only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr
and use use it to pint to the data.– Frankie_C
Nov 25 '18 at 21:04
I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in
loadData()
only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointer cr
and use use it to pint to the data.– Frankie_C
Nov 25 '18 at 21:04
I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.
– Arkadijus
Nov 25 '18 at 21:20
I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.
– Arkadijus
Nov 25 '18 at 21:20
To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..
– too honest for this site
Nov 25 '18 at 21:22
To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..
– too honest for this site
Nov 25 '18 at 21:22
add a comment |
3 Answers
3
active
oldest
votes
Car *pnt
this is a pointer to Car
.
The expression *(...)
dereferences the ...
into an object.
The expression a[b]
is equal to *(a + b)
.
Car* carPtr
in a function parameter list (ie. in function(... Car *carPtr ....)
is equal to:
Car **carPtr
This is a pointer to a pointer to Car.
&carPtr[x]
is equal to:
carPtr + x
which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:
&(*carPtr)[x]
which is equal to:
((*carPtr) + x)
So try:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
Also I would rewrite the
(*carPtr+number-1)->
into
(*carPtr)[number - 1].
as to indicate that you are handling a pointer to an array.
But really, I would rewrite the api to handle better abstraction:
struct cars_s {
Car *cars;
size_t carslen;
};
int main() {
struct cars_s cars;
insertData(db, &cars);
...
editData(db, &cars);
}
which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars)
and cars->cars[x].year = year
instead of Cars *cars, int *size
and (*carPtr)[x].year = year
.
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Do youmemset(cars, 0, sizeof(Car))
or callcalloc
on allocation? If not, there will be random values after the null terminator in string.
– Kamil Cuk
Nov 25 '18 at 21:16
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
add a comment |
fwrite
expects a pointer to a byte buffer to write.
If you have a local variable (including structure), you would need to get its address with the & operator, like this:
Car myCar;
fwrite(&myCar, sizeof(Car), 1, fout);
But, if you already have a pointer, then you don't need the & opertator:
Car *myCar;
fwrite(myCar, sizeof(Car), 1, fout);
Same thing goes if you have an array of pointers to structures:
Car* cars;
fwrite(cars[i], sizeof(Car), 1, fout);
Since cars[i]
already has the address fwrite
needs, there is no need for any operators.
One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).
So, those 15 char
arrays may have an extra byte appended to round to 16.
If you write the whole structure to file, those bytes will also be written.
This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
add a comment |
The problem was not fwrite, but fseek after all.
This:
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
must be changed to this:
fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);
I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.
As for correct way to write fwrite:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
This works perfectly
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53471806%2ffwrite-a-dynamic-structure-passed-by-reference%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Car *pnt
this is a pointer to Car
.
The expression *(...)
dereferences the ...
into an object.
The expression a[b]
is equal to *(a + b)
.
Car* carPtr
in a function parameter list (ie. in function(... Car *carPtr ....)
is equal to:
Car **carPtr
This is a pointer to a pointer to Car.
&carPtr[x]
is equal to:
carPtr + x
which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:
&(*carPtr)[x]
which is equal to:
((*carPtr) + x)
So try:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
Also I would rewrite the
(*carPtr+number-1)->
into
(*carPtr)[number - 1].
as to indicate that you are handling a pointer to an array.
But really, I would rewrite the api to handle better abstraction:
struct cars_s {
Car *cars;
size_t carslen;
};
int main() {
struct cars_s cars;
insertData(db, &cars);
...
editData(db, &cars);
}
which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars)
and cars->cars[x].year = year
instead of Cars *cars, int *size
and (*carPtr)[x].year = year
.
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Do youmemset(cars, 0, sizeof(Car))
or callcalloc
on allocation? If not, there will be random values after the null terminator in string.
– Kamil Cuk
Nov 25 '18 at 21:16
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
add a comment |
Car *pnt
this is a pointer to Car
.
The expression *(...)
dereferences the ...
into an object.
The expression a[b]
is equal to *(a + b)
.
Car* carPtr
in a function parameter list (ie. in function(... Car *carPtr ....)
is equal to:
Car **carPtr
This is a pointer to a pointer to Car.
&carPtr[x]
is equal to:
carPtr + x
which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:
&(*carPtr)[x]
which is equal to:
((*carPtr) + x)
So try:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
Also I would rewrite the
(*carPtr+number-1)->
into
(*carPtr)[number - 1].
as to indicate that you are handling a pointer to an array.
But really, I would rewrite the api to handle better abstraction:
struct cars_s {
Car *cars;
size_t carslen;
};
int main() {
struct cars_s cars;
insertData(db, &cars);
...
editData(db, &cars);
}
which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars)
and cars->cars[x].year = year
instead of Cars *cars, int *size
and (*carPtr)[x].year = year
.
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Do youmemset(cars, 0, sizeof(Car))
or callcalloc
on allocation? If not, there will be random values after the null terminator in string.
– Kamil Cuk
Nov 25 '18 at 21:16
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
add a comment |
Car *pnt
this is a pointer to Car
.
The expression *(...)
dereferences the ...
into an object.
The expression a[b]
is equal to *(a + b)
.
Car* carPtr
in a function parameter list (ie. in function(... Car *carPtr ....)
is equal to:
Car **carPtr
This is a pointer to a pointer to Car.
&carPtr[x]
is equal to:
carPtr + x
which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:
&(*carPtr)[x]
which is equal to:
((*carPtr) + x)
So try:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
Also I would rewrite the
(*carPtr+number-1)->
into
(*carPtr)[number - 1].
as to indicate that you are handling a pointer to an array.
But really, I would rewrite the api to handle better abstraction:
struct cars_s {
Car *cars;
size_t carslen;
};
int main() {
struct cars_s cars;
insertData(db, &cars);
...
editData(db, &cars);
}
which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars)
and cars->cars[x].year = year
instead of Cars *cars, int *size
and (*carPtr)[x].year = year
.
Car *pnt
this is a pointer to Car
.
The expression *(...)
dereferences the ...
into an object.
The expression a[b]
is equal to *(a + b)
.
Car* carPtr
in a function parameter list (ie. in function(... Car *carPtr ....)
is equal to:
Car **carPtr
This is a pointer to a pointer to Car.
&carPtr[x]
is equal to:
carPtr + x
which is not what you want. You have a pointer to an array of cars, not an array of pointers to cars. You want first to derefernce carPtr, then increment. You want:
&(*carPtr)[x]
which is equal to:
((*carPtr) + x)
So try:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
Also I would rewrite the
(*carPtr+number-1)->
into
(*carPtr)[number - 1].
as to indicate that you are handling a pointer to an array.
But really, I would rewrite the api to handle better abstraction:
struct cars_s {
Car *cars;
size_t carslen;
};
int main() {
struct cars_s cars;
insertData(db, &cars);
...
editData(db, &cars);
}
which will make you code more readable, when you do editData(FILE *db, struct cars_s *cars)
and cars->cars[x].year = year
instead of Cars *cars, int *size
and (*carPtr)[x].year = year
.
edited Nov 25 '18 at 21:06
answered Nov 25 '18 at 21:01
Kamil CukKamil Cuk
12.2k1529
12.2k1529
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Do youmemset(cars, 0, sizeof(Car))
or callcalloc
on allocation? If not, there will be random values after the null terminator in string.
– Kamil Cuk
Nov 25 '18 at 21:16
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
add a comment |
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Do youmemset(cars, 0, sizeof(Car))
or callcalloc
on allocation? If not, there will be random values after the null terminator in string.
– Kamil Cuk
Nov 25 '18 at 21:16
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Thanks for your answer. It compiles, but I have same problem as with the answer above, file gets filled with random values.
– Arkadijus
Nov 25 '18 at 21:15
Do you
memset(cars, 0, sizeof(Car))
or call calloc
on allocation? If not, there will be random values after the null terminator in string.– Kamil Cuk
Nov 25 '18 at 21:16
Do you
memset(cars, 0, sizeof(Car))
or call calloc
on allocation? If not, there will be random values after the null terminator in string.– Kamil Cuk
Nov 25 '18 at 21:16
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Tried using memset on allocation, but unless I have used it wrong, it did not help. I do not think that structure is bad, as I printf it to check and it looks the way it should be. I think it fails at fwrite step.
– Arkadijus
Nov 25 '18 at 21:31
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
Then, create an MCVE, which I can copy&paste in to my editor. Without a minimal example, it's just guesses.
– Kamil Cuk
Nov 25 '18 at 21:47
add a comment |
fwrite
expects a pointer to a byte buffer to write.
If you have a local variable (including structure), you would need to get its address with the & operator, like this:
Car myCar;
fwrite(&myCar, sizeof(Car), 1, fout);
But, if you already have a pointer, then you don't need the & opertator:
Car *myCar;
fwrite(myCar, sizeof(Car), 1, fout);
Same thing goes if you have an array of pointers to structures:
Car* cars;
fwrite(cars[i], sizeof(Car), 1, fout);
Since cars[i]
already has the address fwrite
needs, there is no need for any operators.
One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).
So, those 15 char
arrays may have an extra byte appended to round to 16.
If you write the whole structure to file, those bytes will also be written.
This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
add a comment |
fwrite
expects a pointer to a byte buffer to write.
If you have a local variable (including structure), you would need to get its address with the & operator, like this:
Car myCar;
fwrite(&myCar, sizeof(Car), 1, fout);
But, if you already have a pointer, then you don't need the & opertator:
Car *myCar;
fwrite(myCar, sizeof(Car), 1, fout);
Same thing goes if you have an array of pointers to structures:
Car* cars;
fwrite(cars[i], sizeof(Car), 1, fout);
Since cars[i]
already has the address fwrite
needs, there is no need for any operators.
One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).
So, those 15 char
arrays may have an extra byte appended to round to 16.
If you write the whole structure to file, those bytes will also be written.
This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
add a comment |
fwrite
expects a pointer to a byte buffer to write.
If you have a local variable (including structure), you would need to get its address with the & operator, like this:
Car myCar;
fwrite(&myCar, sizeof(Car), 1, fout);
But, if you already have a pointer, then you don't need the & opertator:
Car *myCar;
fwrite(myCar, sizeof(Car), 1, fout);
Same thing goes if you have an array of pointers to structures:
Car* cars;
fwrite(cars[i], sizeof(Car), 1, fout);
Since cars[i]
already has the address fwrite
needs, there is no need for any operators.
One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).
So, those 15 char
arrays may have an extra byte appended to round to 16.
If you write the whole structure to file, those bytes will also be written.
This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.
fwrite
expects a pointer to a byte buffer to write.
If you have a local variable (including structure), you would need to get its address with the & operator, like this:
Car myCar;
fwrite(&myCar, sizeof(Car), 1, fout);
But, if you already have a pointer, then you don't need the & opertator:
Car *myCar;
fwrite(myCar, sizeof(Car), 1, fout);
Same thing goes if you have an array of pointers to structures:
Car* cars;
fwrite(cars[i], sizeof(Car), 1, fout);
Since cars[i]
already has the address fwrite
needs, there is no need for any operators.
One thing to note is that C compilers pad structures - they may insert unused bytes between fields to make sure each field starts on a boundary (depends on your system word alignment, usually 4).
So, those 15 char
arrays may have an extra byte appended to round to 16.
If you write the whole structure to file, those bytes will also be written.
This is why it is usually recommended to write each field separately, but if this is just an exercise, it may not matter.
answered Nov 25 '18 at 20:57
Lev M.Lev M.
768314
768314
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
add a comment |
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
Thanks for your answer, but it does not work yet. Program compiles successfully, but fwrite writes something random, not what I want to write. Structure itself seems to be good, as I print entire structure to check.
– Arkadijus
Nov 25 '18 at 21:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
How are you looking at the file? Are you using a hex editor? Windows Notepad?
– Lev M.
Nov 25 '18 at 22:13
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Another function freads file to a structure which i print afterwards.
– Arkadijus
Nov 25 '18 at 22:26
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
Is it possible the read function is incorrect? Try looking at the file with hex editor.
– Lev M.
Nov 26 '18 at 5:34
add a comment |
The problem was not fwrite, but fseek after all.
This:
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
must be changed to this:
fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);
I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.
As for correct way to write fwrite:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
This works perfectly
add a comment |
The problem was not fwrite, but fseek after all.
This:
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
must be changed to this:
fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);
I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.
As for correct way to write fwrite:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
This works perfectly
add a comment |
The problem was not fwrite, but fseek after all.
This:
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
must be changed to this:
fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);
I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.
As for correct way to write fwrite:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
This works perfectly
The problem was not fwrite, but fseek after all.
This:
fseek(fPtr, sizeof(Car) * number-1, SEEK_SET);
must be changed to this:
fseek(fPtr, sizeof(Car) * (number-1), SEEK_SET);
I've managed to omit parenthesis and because of this fwrite would write to wrong place. Fread would then read more than there is memory allocated and thats why I think random things happened.
As for correct way to write fwrite:
fwrite(&(*carPtr)[number-1], sizeof(Car), 1, fPtr);
This works perfectly
answered Nov 26 '18 at 13:25
ArkadijusArkadijus
145
145
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53471806%2ffwrite-a-dynamic-structure-passed-by-reference%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
How is
Car
declared?– Kamil Cuk
Nov 25 '18 at 20:53
1
Edited my question to include it
– Arkadijus
Nov 25 '18 at 20:57
I think you're messing up things. What you call "passing parameters for reference", inexistent concept in C, is used in
loadData()
only because there the memory is allocated and the data retrieved from database and load in it, passing the address of the pointer allows to set its value. In the other functions you must simply pass the pointercr
and use use it to pint to the data.– Frankie_C
Nov 25 '18 at 21:04
I think I tried passing cr before, but then the structure got changed only locally, outside of the function it did not.
– Arkadijus
Nov 25 '18 at 21:20
To elaborate on @Frankie_C s comment: C does not support references, it is strictly pass-by-value. A pointer is a first class type..
– too honest for this site
Nov 25 '18 at 21:22