Writing/reading C 中的二维字符数组到二进制文件
Writing/reading 2D char array in C to binary file
我有一个数组,其中包含 6 个单词和一个秘密单词
char boardInputs[7][6];
每次用户输入单词时,我都需要将这个数组自动保存到二进制文件中。重启程序后,我需要从二进制文件中读取保存的words数组,并将其安装到板子的输入数据数组中
void readArray(int rows, int cols, char array[rows][cols]) {
FILE *data;
data = fopen("autosave.bin", "rb");
fread(array, sizeof(char[rows][cols]), 1, data);
}
void autoSave() {
int result = EXIT_SUCCESS;
char file_name[] = "autosave.bin";
FILE *fp = fopen(file_name, "wb");
if (fp == NULL) {
result = EXIT_FAILURE;
fprintf(stderr, "fopen() failed for '%s'\n", file_name);
} else {
size_t element_size = sizeof *boardInputs;
size_t elements_to_write = sizeof boardInputs;
size_t elements_written = fwrite(boardInputs, element_size, elements_to_write, fp);
if (elements_written != elements_to_write) {
result = EXIT_FAILURE;
fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n",
elements_written, elements_to_write);
}
fclose(fp);
}
}
int main() {
int cols = 7;
int rows = 6;
char (*myArray)[cols] = allocArray(rows, cols);
readArray(rows, cols, myArray);
strcpy(boardInputs, myArray);
free(myArray);
}
我创建了这段代码,但是二进制文件中的单词设置不正确。如何解决?
autoSave()
使用不正确的参数调用 fwrite()
,sizeof boardInputs
是二维数组的总大小,因此元素数为 1。这是关键问题。
autoSave()
不会 return 消除任何东西 result
.
autoSave()
和 readArray()
hard-code 相同的路径,因此将其设为定义而不是重复。
readArray()
依赖于全局变量,因此将行和列提升为宏常量并简化了参数数量。
readArray()
应该关闭 data
文件句柄。
main()
应该 return 一个整数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 7
#define COLS 6
#define PATH "autosave.bin"
char boardInputs[ROWS][COLS];
void autoSave() {
FILE *fp = fopen(PATH, "wb");
if(!fp) {
fprintf(stderr, "fopen() failed for '%s'\n", PATH);
return;
}
size_t elements_to_write = sizeof boardInputs;
size_t elements_written = fwrite(boardInputs, 1, elements_to_write, fp);
if (elements_written != elements_to_write) {
fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n",
elements_written, elements_to_write);
}
fclose(fp);
}
void printArray(char array[ROWS][COLS]) {
for(int i = 0; i < ROWS; i++) {
printf("%d: %s\n", i, array[i]);
}
}
void readArray(char array[ROWS][COLS]) {
FILE *data = fopen(PATH, "rb");
fread(array, sizeof(char[ROWS][COLS]), 1, data);
fclose(data);
}
int main() {
for(unsigned i = 0; i < 7; i++) {
char s[7];
sprintf(s, "%u", i);
strcpy(boardInputs[i], s);
}
printArray(boardInputs);
autoSave();
char myArray[ROWS][COLS];
readArray(myArray);
printArray(myArray);
return 0;
}
输出表明读写具有相同的值:
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
您的代码中存在多个问题:
- 您没有在
readArray
中测试 fopen()
失败;
- 您没有关闭
read_array
中的文件;
result
在 autoSave
中未使用;
strcpy
复制整板不正确。您应该测试 readArray
是否成功并使用 memcpy
;
autoSave
中的大小不正确:size_t element_size = sizeof *boardInputs
计算出一个字的大小,即6个字节,size_t elements_to_write = sizeof boardInputs
是整个数组的字节大小。 fwrite
将尝试写入 6 * 42
字节,当它访问超出其边界的 boardInputs
时导致未定义的行为。数组的长度是它的大小除以元素大小。在这种情况下,最好以字节为单位,而不是以字为单位;
- 为了保证
boardInputs
和myArray
的一致性,需要在构造中定义相同的大小
这是修改后的版本:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_COUNT 7
#define WORD_LEN 6
char boardInputs[WORD_COUNT][WORD_LEN];
const char *autoSaveFilename = "autosave.bin";
int readArray(int rows, int cols, char array[rows][cols]) {
FILE *fp = fopen(autoSaveFilename, "rb");
if (fp == NULL)
return -1;
int n = fread(array, sizeof(char[rows][cols]), 1, fp);
fclose(fp);
return n == 1 ? 0 : -1;
}
int autoSave(void) {
int result = EXIT_SUCCESS;
FILE *fp = fopen(autoSaveFilename, "wb");
if (fp == NULL) {
result = EXIT_FAILURE;
fprintf(stderr, "fopen() failed for '%s': %s\n",
autoSaveFilename, strerror(errno));
} else {
size_t element_size = 1;
size_t elements_to_write = sizeof(boardInputs);
size_t elements_written = fwrite(boardInputs, 1, elements_to_write, fp);
if (elements_written != elements_to_write) {
result = EXIT_FAILURE;
fprintf(stderr, "fwrite() failed: wrote only %zu bytes out of %zu.\n",
elements_written, elements_to_write);
}
fclose(fp);
}
return result;
}
int main() {
char myArray[WORD_COUNT][WORD_LEN];
if (!readArray(WORD_COUNT, WORD_LEN, myArray))
memcpy(boardInputs, myArray, sizeof boardInputs);
return 0;
}
我有一个数组,其中包含 6 个单词和一个秘密单词
char boardInputs[7][6];
每次用户输入单词时,我都需要将这个数组自动保存到二进制文件中。重启程序后,我需要从二进制文件中读取保存的words数组,并将其安装到板子的输入数据数组中
void readArray(int rows, int cols, char array[rows][cols]) {
FILE *data;
data = fopen("autosave.bin", "rb");
fread(array, sizeof(char[rows][cols]), 1, data);
}
void autoSave() {
int result = EXIT_SUCCESS;
char file_name[] = "autosave.bin";
FILE *fp = fopen(file_name, "wb");
if (fp == NULL) {
result = EXIT_FAILURE;
fprintf(stderr, "fopen() failed for '%s'\n", file_name);
} else {
size_t element_size = sizeof *boardInputs;
size_t elements_to_write = sizeof boardInputs;
size_t elements_written = fwrite(boardInputs, element_size, elements_to_write, fp);
if (elements_written != elements_to_write) {
result = EXIT_FAILURE;
fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n",
elements_written, elements_to_write);
}
fclose(fp);
}
}
int main() {
int cols = 7;
int rows = 6;
char (*myArray)[cols] = allocArray(rows, cols);
readArray(rows, cols, myArray);
strcpy(boardInputs, myArray);
free(myArray);
}
我创建了这段代码,但是二进制文件中的单词设置不正确。如何解决?
autoSave()
使用不正确的参数调用fwrite()
,sizeof boardInputs
是二维数组的总大小,因此元素数为 1。这是关键问题。autoSave()
不会 return 消除任何东西result
.autoSave()
和readArray()
hard-code 相同的路径,因此将其设为定义而不是重复。readArray()
依赖于全局变量,因此将行和列提升为宏常量并简化了参数数量。readArray()
应该关闭data
文件句柄。main()
应该 return 一个整数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 7
#define COLS 6
#define PATH "autosave.bin"
char boardInputs[ROWS][COLS];
void autoSave() {
FILE *fp = fopen(PATH, "wb");
if(!fp) {
fprintf(stderr, "fopen() failed for '%s'\n", PATH);
return;
}
size_t elements_to_write = sizeof boardInputs;
size_t elements_written = fwrite(boardInputs, 1, elements_to_write, fp);
if (elements_written != elements_to_write) {
fprintf(stderr, "fwrite() failed: wrote only %zu out of %zu elements.\n",
elements_written, elements_to_write);
}
fclose(fp);
}
void printArray(char array[ROWS][COLS]) {
for(int i = 0; i < ROWS; i++) {
printf("%d: %s\n", i, array[i]);
}
}
void readArray(char array[ROWS][COLS]) {
FILE *data = fopen(PATH, "rb");
fread(array, sizeof(char[ROWS][COLS]), 1, data);
fclose(data);
}
int main() {
for(unsigned i = 0; i < 7; i++) {
char s[7];
sprintf(s, "%u", i);
strcpy(boardInputs[i], s);
}
printArray(boardInputs);
autoSave();
char myArray[ROWS][COLS];
readArray(myArray);
printArray(myArray);
return 0;
}
输出表明读写具有相同的值:
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
您的代码中存在多个问题:
- 您没有在
readArray
中测试fopen()
失败; - 您没有关闭
read_array
中的文件; result
在autoSave
中未使用;strcpy
复制整板不正确。您应该测试readArray
是否成功并使用memcpy
;autoSave
中的大小不正确:size_t element_size = sizeof *boardInputs
计算出一个字的大小,即6个字节,size_t elements_to_write = sizeof boardInputs
是整个数组的字节大小。fwrite
将尝试写入6 * 42
字节,当它访问超出其边界的boardInputs
时导致未定义的行为。数组的长度是它的大小除以元素大小。在这种情况下,最好以字节为单位,而不是以字为单位;- 为了保证
boardInputs
和myArray
的一致性,需要在构造中定义相同的大小
这是修改后的版本:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_COUNT 7
#define WORD_LEN 6
char boardInputs[WORD_COUNT][WORD_LEN];
const char *autoSaveFilename = "autosave.bin";
int readArray(int rows, int cols, char array[rows][cols]) {
FILE *fp = fopen(autoSaveFilename, "rb");
if (fp == NULL)
return -1;
int n = fread(array, sizeof(char[rows][cols]), 1, fp);
fclose(fp);
return n == 1 ? 0 : -1;
}
int autoSave(void) {
int result = EXIT_SUCCESS;
FILE *fp = fopen(autoSaveFilename, "wb");
if (fp == NULL) {
result = EXIT_FAILURE;
fprintf(stderr, "fopen() failed for '%s': %s\n",
autoSaveFilename, strerror(errno));
} else {
size_t element_size = 1;
size_t elements_to_write = sizeof(boardInputs);
size_t elements_written = fwrite(boardInputs, 1, elements_to_write, fp);
if (elements_written != elements_to_write) {
result = EXIT_FAILURE;
fprintf(stderr, "fwrite() failed: wrote only %zu bytes out of %zu.\n",
elements_written, elements_to_write);
}
fclose(fp);
}
return result;
}
int main() {
char myArray[WORD_COUNT][WORD_LEN];
if (!readArray(WORD_COUNT, WORD_LEN, myArray))
memcpy(boardInputs, myArray, sizeof boardInputs);
return 0;
}