fwrite() 如果任何单个字节的符号位为 1,则将全 1 写入更高有效位(写入 int)
fwrite() writing all 1's to more significant bits if sign bit of any single byte is 1 (writing int)
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 是指向结构实例的指针,如下所示:
struct part{
int num;
int qoh;
char *name;
struct part *next;
};
如果我将数字 8、104、3176 等存储在 num 中,一切都很好。但是,如果我存储 128、32768 或任何使用字节最高有效位的数字(字节为 1XXX-XXX 的任何数字),fwrite 会将所有 1 写入文件中所有更重要的字节,将 128 转换为-128、199 到 -57 等
这种字节更改不会在程序执行期间发生 - 仅在保存到文件时发生。查看 num = 199 和 qoh = 3,写入文件后,字节是这样的:
ff ff ff c7 00 00 00 03
应该是
00 00 00 c7 00 00 00 03
我将文件加载到清单程序中,它按预期加载了字节。 num = -57,不是 199。
我是不是用错了fwrite?
这是存储部分,应要求。
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;
}
和保存功能:
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?
不,你正在正确使用它。因此,结果的问题与您正在写入的数据或您正在写入的流有关。
考虑这个根据您的原始代码示例改编的完整程序:
#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;
}
这 将是一个合理的 MCVE,除了它实际上并没有为我重现错误这一事实。这是结果输出的十六进制转储:
c7 00 00 00 03 00 00 00 46 6f 6f 00
从这里您可以看到我的机器对其 int
使用小端表示法,而且它不会产生您所描述的损坏的整数。
回答了你的基本问题后,我不想整理你相对大量的代码来找出问题出现的位置和方式。然而,我仍然建议将其简化为 MCVE,因为这很有可能帮助您自己发现问题的本质,或者至少是其中涉及的关键陈述。
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 是指向结构实例的指针,如下所示:
struct part{
int num;
int qoh;
char *name;
struct part *next;
};
如果我将数字 8、104、3176 等存储在 num 中,一切都很好。但是,如果我存储 128、32768 或任何使用字节最高有效位的数字(字节为 1XXX-XXX 的任何数字),fwrite 会将所有 1 写入文件中所有更重要的字节,将 128 转换为-128、199 到 -57 等
这种字节更改不会在程序执行期间发生 - 仅在保存到文件时发生。查看 num = 199 和 qoh = 3,写入文件后,字节是这样的:
ff ff ff c7 00 00 00 03
应该是
00 00 00 c7 00 00 00 03
我将文件加载到清单程序中,它按预期加载了字节。 num = -57,不是 199。
我是不是用错了fwrite?
这是存储部分,应要求。
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;
}
和保存功能:
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?
不,你正在正确使用它。因此,结果的问题与您正在写入的数据或您正在写入的流有关。
考虑这个根据您的原始代码示例改编的完整程序:
#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;
}
这 将是一个合理的 MCVE,除了它实际上并没有为我重现错误这一事实。这是结果输出的十六进制转储:
c7 00 00 00 03 00 00 00 46 6f 6f 00
从这里您可以看到我的机器对其 int
使用小端表示法,而且它不会产生您所描述的损坏的整数。
回答了你的基本问题后,我不想整理你相对大量的代码来找出问题出现的位置和方式。然而,我仍然建议将其简化为 MCVE,因为这很有可能帮助您自己发现问题的本质,或者至少是其中涉及的关键陈述。