C 下标值不是数组也不是指针

C 下标值不是数组也不是指针,c,arrays,malloc,realloc,C,Arrays,Malloc,Realloc,我有一个程序,可以从文件中读取2d数组,并使其成为锯齿状数组(其中每行的大小完全适合所有非零元素)。然后打印出阵列 但我有两个问题想不通 具体地 26:我得到一个警告(赋值从指针生成整数而不强制转换) 44:错误:下标值既不是数组也不是指针 我能做些什么来修复它 int main() { FILE *inputFile1 = fopen("denseMatrix1.txt", "r"); char inputBuffer[SIZE]; int dim1

我有一个程序,可以从文件中读取2d数组,并使其成为锯齿状数组(其中每行的大小完全适合所有非零元素)。然后打印出阵列

但我有两个问题想不通

具体地

26:我得到一个警告(赋值从指针生成整数而不强制转换)

44:错误:下标值既不是数组也不是指针

我能做些什么来修复它

int main() {

FILE *inputFile1 = fopen("denseMatrix1.txt", "r");

char inputBuffer[SIZE];
int dim1, dim2, input, i, j;
int *mtrx1;

fgets(inputBuffer, SIZE, inputFile1);
sscanf(inputBuffer, "%d%d", &dim1, &dim2);

mtrx1 = malloc(sizeof(int *) * dim1);

for (i=0; i<dim1; i++) {
    int cols=0;
    int *row = malloc(sizeof(int) * cols);
    fgets(inputBuffer, SIZE, inputFile1);
    for (j=0; j<dim2; j++) {
        sscanf(inputBuffer, "%d", input);
        printf("i=%d   j=%d    input=%d\n", i, j, input); // ADDED LINE (NOT PRINTING)
        if (input) {
            cols++;
            row = realloc(row, sizeof(int) * cols);
            row[cols-1] = input;
        }
    }
    mtrx1[i] = row;
    cols=0;
}

int mtrx3[DIM1][DIM2] = {0};

// Prints first 2 matrices
printf("First matrix: \n");
printMatrix(mtrx1, dim1);/*

return 0;


// Prints a 2d array matrix
void printMatrix(int *mtrx, int dim1) {
int i, j;
for (i=0; i<dim1; i++) {
    for (j=0; j<(sizeof(mtrx[i]) / sizeof(int)); j++) {
        printf("%d ", mtrx[i][j]);
    }
    printf("\n");
}
printf("\n\n");
代替

int *mtrx1;
使用

对于前一个声明,
mtrx[i]
的计算结果为
int
。您需要将其计算为
int*
,才能使用:

mtrx1[i] = row;
更新

您使用
fgets
获取一行文本并将该行文本与
sscanf
一起使用的策略不会在
for
循环中起作用

让我们看一下矩阵的第一行:

0 0 0 5 1 0 0 5
以及循环的

for (j=0; j<dim2; j++) {
    sscanf(inputBuffer, "%d", input);
    printf("i=%d   j=%d    input=%d\n", i, j, input); // ADDED LINE (NOT PRINTING)
    if (input) {
        cols++;
        row = realloc(row, sizeof(int) * cols);
        row[cols-1] = input;
    }
}
第26行警告 这是有问题的一句话:

mtrx1[i] = row;
以下是这些变量的声明:

int *mtrx1;
int ..., i, ...;
int *row = ...;
正如您的警告消息所说,您试图获取一个指针值,
row
,并将其分配给
int
s数组。假设您想要的是
mtrx1
成为单个
row
子数组的数组,您应该相应地更改其类型–从
int*
,即
int数组de>s,到
int**
,这将是
int
s的数组

第44行错误 相关代码:

void printMatrix(int *mtrx, int dim1) {
    int i, j;
    ...
    printf("%d ", mtrx[i][j]); // line 44
    ...
}
这一行上的错误是与上述问题类似的问题的结果—
mtrx
被声明为
int
的一维数组,但在第44行中,您有两个下标,就好像它是二维数组一样。通过将
mtrx
的类型更改为
int**
也可以解决这一问题

For循环
for
循环无法迭代所有值,因为您的
sscanf
行不明确–您的
%d
值之间没有空格,因此
sscanf
无法判断哪个数字应该是哪个,它将它们作为一个值读取。这意味着
dim2
从未正确设置

对于这类bug,使用断点通常是了解程序中发生了什么的最简单的方法,尤其是对于循环。如果您还没有研究它们,您应该这样做

附加信息 第26行给您一个警告,而第44行给您一个错误,这是因为C中指针相对于INT的定义方式。C允许“指针算术”,这意味着指针除了引用对象或数组外,还可以被视为普通数字

在C中为数组下标时,表达式的类型实际上只会删除一个
*
;例如,下标
int*
数组的类型为
int
。因此,当您尝试将指针分配给
int*mtrx1
时,它将其视为尝试将指针分配给
int
变量,因此指针r被转换成它的原始数值。这是完全合法的C,但大多数程序员认为这是相当糟糕的做法(出于各种原因),因此编译器会给你一个警告


第44行有点相反–您的
mtrx[i][j]
表达式相当于
(mtrx[i])[j]
。由于
mtrx
被定义为一个
int*
,这意味着您实际上最终尝试下标一个
int
,这在C中完全是非法的。没有警告,只是一个错误。

新策略是有意义的,但我收到了关于在不使用强制转换的情况下进行赋值的警告。而且它仍然不会打印printf。我真的不知道还能做什么,但我必须使用sscanf。这段代码没有编译,语法中有几个错误,例如这行末尾的“*”:printMatrix(mtrx1,dim1);/*即使没有这个错误,main()结尾的结尾“}”函数丢失,printMatrix()函数的其余部分也丢失。需要检查I/O输入函数(scanf、fgets)返回的值,以确保实际执行了所需的操作。由于输入中仍存在空白(例如换行符),scanf()的格式字符串将失败。若要解决此问题,格式Strings中需要有一个前导“”。如果调用realloc()失败,则下一行代码将导致seg错误事件。即,在使用变量“input”之前测试返回值。未定义该变量。您是否尝试编译此代码?
mtrx1[i] = row;
int *mtrx1;
int ..., i, ...;
int *row = ...;
void printMatrix(int *mtrx, int dim1) {
    int i, j;
    ...
    printf("%d ", mtrx[i][j]); // line 44
    ...
}