for (struct part *p = first; p != NULL; p = p->next;) {
fwrite(&(p->num), sizeof(int), 1, inventory);
fwrite(&(p->qoh), sizeof(int), 1, inventory);
fwrite(p->name, sizeof(char), strlen(p->name) + 1, inventory);
}
p is a pointer to a struct instance that looks like this:
struct part{
int num;
int qoh;
char *name;
struct part *next;
};
If i store the number 8, 104, 3176, etc. in num, things are fine. However, if I store 128, 32768, or any number that uses the most significant bit of a byte (any number with a byte 1XXX-XXX), fwrite writes all 1's into all of the more significant bytes in the file, turning 128 to -128, 199 to -57, etc.
This changing of the bytes doesn't happen during program execution - only on saving to file. Looking at num = 199 and qoh = 3, after written to file, the bytes are as such:
ff ff ff c7 00 00 00 03
which should be
00 00 00 c7 00 00 00 03
I load the file into the inventory program and it loads as expected looking at the bytes. num = -57, not 199.
Am I using fwrite wrong?
Here's the storing part, as requested.
void part_new(void) {
struct part *new;
int num, qoh;
char *name;
printf("\nEnter a part number: ");
scanf("%d", &num);
while(getchar() != '\n');
for (struct part *p = first; p != NULL; p = p->next) {
if (p->num == num) {
printf("Duplicate part number, name: %s. Canceling action.\n", p->name);
return;
}
}
printf("Enter a name: ");
if ((name = input(PART_NAME_MAX_CHARS)) == NULL) {
printf("Bad input.\n");
return;
}
printf("Enter a QOH: ");
scanf("%d", &qoh);
while(getchar() != '\n');
new = malloc(sizeof(struct part));
new->num = num;
new->qoh = qoh;
new->name = malloc(strlen(name) + 1);
strncpy(new->name, name, strlen(name) + 1);
free(name);
part_into_list(new);
return;
}
and the save function:
bool save_file(char *fname) {
FILE *inventory;
struct part *del;
if ((inventory = fopen(fname, "wb")) == NULL) {
printf("\nCould not save %s.\n", fname);
return false;
}
fseek(inventory, 0 , SEEK_SET);
for (struct part *p = first; p != NULL; p = p->next) {
fwrite(&(p->num), sizeof(int), 1, inventory);
fwrite(&(p->qoh), sizeof(int), 1, inventory);
fwrite(p->name, sizeof(char), strlen(p->name) + 1, inventory);
}
printf("%s saved.\n", fname);
fclose(inventory);
return true;
}
Am I using fwrite wrong?
No, you are using it correctly. Ergo, the problem with the result has to do either with the data you are writing or the stream you are writing it to.
Consider this complete program, adapted from your original code sample:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct part{
int num;
int qoh;
char *name;
struct part *next;
};
int main(void) {
struct part sp = { 199, 3, "Foo" };
FILE *fp = fopen("out", "wb");
for (struct part *p = &sp; p != NULL; p = p->next) {
fwrite(&(p->num), sizeof(int), 1, fp);
fwrite(&(p->qoh), sizeof(int), 1, fp);
fwrite(p->name, sizeof(char), strlen(p->name) + 1, fp);
}
fclose(fp);
return 0;
}
This would be a reasonable MCVE, except for the fact that it does not in fact reproduce the error for me. Here's a hex dump of the resulting output:
c7 00 00 00 03 00 00 00 46 6f 6f 00
From this you can see that my machine uses little-endian representation for its int
s, but also that it does not produce mangled integers such as you describe.
Having answered your basic question, I'm not inclined to sort through your relatively substantial code to figure out where and how the problem arises. I still recommend the exercise of reducing that to an MCVE, however, as that has a decent chance of helping you discover the nature of the problem for yourself, or at least the key statements involved in it.