函数int load(const char *filename, int ***ptr, enum save_format_t format)
应将数据从二进制或文本文件(名称保存在filename
指针下(加载到ptr
指针下的矩阵。文件扩展名取决于变量format的值:0或1(在我展示的函数中,只有format=0的选项,主要用于文本文件,因为只有这个选项会带来麻烦(。文件中的正确数据如下所示:
10 20 30 40 50 60 70-1
100 200 300 400 500 600 700 800-1
对于与上面的示例完全相同的数据,数据应该像这样加载:
int A[] = {10, 20, 30, 40, 50, 60, 70, -1};
int B[] = {100, 200, 300, 400, 500, 600, 700, 800, -1};
int D[] = {A, B, C, NULL};
这意味着每一行都必须以"-1"结尾(数据必须加载到带有"-1"的矩阵中(。指向最后一行之后的行的指针应等于NULL。
如果在任何部分关闭功能分配失败,功能应返回4。
对扩展名为"的文件进行的测试;。bin";并且使用堆限制返回此错误:
函数应该返回4,但它返回了0。
我使用类似**ptr
的表示法,因为不允许使用方括号。
有人能帮我如何让我的函数返回正确的整数吗。我的功能如下:
int load(const char *filename, int ***ptr, enum save_format_t format) {
if (filename == NULL || ptr == NULL || format != 0 && format != 1) {
return 1;
}
int val = 0;
int **temp = NULL;
FILE *fp, *pp;
if (format == 0) {
int i = 0, x = 0, h = 0, w = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 2;
}
pp = fopen(filename, "r");
if (pp == NULL) {
fclose(fp);
return 2;
}
int val2 = 0;
while (1) {
if (fscanf(fp, "%d", &val2) != 1) {
if (i == 0 || val != -1) {
fclose(fp);
fclose(pp);
return 3;
}
break;
}
val = val2;
if (val == -1) {
h++;
}
i++;
}
if (i == h) {
fclose(fp);
fclose(pp);
return 3;
}
i = 0;
fseek(fp, 0, SEEK_SET);
temp = malloc(sizeof(temp) * (h + 1));
if (temp == NULL) {
fclose(fp);
fclose(pp);
return 4;
}
*(temp + h) = NULL;
for (i = 0; i < h; i++) {
val = 0, w = 0;
while (val != -1) {
if (fscanf(pp, "%d", &val) == EOF) {
break;
}
w++;
}
if (*(temp + i) != NULL) {
*(temp + i) = (int *)malloc(sizeof(int) * w);
if (*(temp + i) == NULL) {
for (int s = 0; s < i; s++) {
free(*(temp + s));
}
free(temp);
fclose(pp);
fclose(fp);
return 4;
}
} else {
fclose(fp);
fclose(pp);
free(temp);
return 0;
}
for (x = 0; x < w; x++) {
fscanf(fp, "%d", *(temp + i) + x);
}
}
fclose(fp);
fclose(pp);
}
*ptr = temp;
return 0;
}
您的代码中存在多个问题:
if (i == h)
似乎不正确:如果文件包含带有-1
终止符的单行,换句话说,是一个空矩阵,该怎么办temp = malloc(sizeof(temp) * (h + 1));
应为temp = malloc(sizeof(*temp) * (h + 1));
- CCD_ 9读取由CCD_。应该删除该测试,并且应该始终分配该行
这是一个修改后的版本:
int load(const char *filename, int ***ptr, enum save_format_t format) {
if (filename == NULL || ptr == NULL || format != 0 && format != 1) {
return 1;
}
int **temp = NULL;
FILE *fp, *pp;
if (format == 0) {
int i = 0, x = 0, h = 0, w = 0, val = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 2;
}
pp = fopen(filename, "r");
if (pp == NULL) {
fclose(fp);
return 2;
}
// determine the number of rows
val = 0;
while (fscanf(fp, "%d", &val) == 1) {
if (val == -1)
h++;
}
if (val != -1) {
// empty file or file does not end with -1
fclose(fp);
fclose(pp);
return 3;
}
temp = malloc(sizeof(*temp) * (h + 1));
if (temp == NULL) {
fclose(fp);
fclose(pp);
return 4;
}
fseek(fp, 0, SEEK_SET);
for (i = 0; i < h; i++) {
w = 0;
while (fscanf(pp, "%d", &val) == 1) {
w++;
if (val == -1)
break;
}
if (w == 0 || (*(temp + i) = malloc(sizeof(int) * w)) == NULL) {
while (i-- > 0) {
free(*(temp + i));
}
free(temp);
fclose(pp);
fclose(fp);
return 4;
}
for (x = 0; x < w; x++) {
fscanf(fp, "%d", *(temp + i) + x);
}
}
*(temp + h) = NULL;
fclose(fp);
fclose(pp);
}
*ptr = temp;
return 0;
}
考虑读取字符串并使用strtol
进行解析
当没有可用的RAM时,内存分配将返回NULL。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
int load ( char const *filename, int ***ptr) {
if ( filename == NULL || ptr == NULL) {
return 1;
}
char entry[100] = "";
char *end = NULL;
int **temp = NULL;
int *temprow = NULL;
long int val = 0;
int rows = 0;
int cols = 0;
int problem = 0;
int result = 0;
FILE* fp = NULL;
fp = fopen ( filename, "r");
if ( fp == NULL) {
perror ( filename);
return 2;
}
while ( 1 == ( result = fscanf ( fp, "%99s", entry))) {
if ( -1 == val || ( 0 == rows && 0 == cols)) {
if ( -1 == val) {
++rows;
}
if ( NULL == ( temp = realloc ( *ptr, sizeof **ptr * ( rows + 2)))) {
fprintf ( stderr, "problem realloc *ptrn");
problem = 4;
break;
}
*ptr = temp;
*( ( *ptr) + rows) = NULL;
*( ( *ptr) + rows + 1) = NULL;//sentinel
cols = 0;
}
errno = 0;
val = strtol ( entry, &end, 10);
if ( entry == end) {//nothing could be parsed to int
problem = 3;
break;
}
else if ( 0 != *end) {//extra characters after int
problem = 3;
break;
}
if ( ( errno == ERANGE && ( val == LONG_MAX || val == LONG_MIN))
|| ( errno != 0 && val == 0)) {// parsing error from strtol
perror ( "input error");
problem = 3;
break;
}
if ( val > INT_MAX || val < INT_MIN) {
problem = 3;
break;
}
if ( NULL == ( temprow = realloc ( *( ( *ptr) + rows), sizeof ***ptr * ( cols + 2)))) {
fprintf ( stderr, "problem realloc *( (*ptr) + row)n");
problem = 4;
break;
}
*( ( *ptr) + rows) = temprow;
++cols;
*( *( ( *ptr) + rows)) = cols;//save cols in index 0
*( *( ( *ptr) + rows) + cols) = val;
}
fclose(fp);
if ( 0 == result) {
problem = 3;
}
return problem;
}
int main ( void) {
char const *filename = "ints.txt";
int **array = NULL;
int row = 0;
int each = 0;
load ( filename, &array);
row = 0;
while ( array && ( *(array + row))) {
each = 0;
while ( each <= *( *(array + row))) {
printf ( "%dn", *( *(array + row) + each));
++each;
}
++row;
}
row = 0;
while ( array && ( *(array + row))) {
free ( *(array + row));
++row;
}
free ( array);
return 0;
}