этот код возвращает ошибку сегментации.
см. Примечание о malloc ниже
Некоторые замечания сверху внизкод
В
int row;
int column;
Почему эти две глобальные переменные?они могут быть локальными в main
В
fp = fopen("file.path", "r");
fscanf(fp, "%d", &row);
fgetc(fp);
fscanf(fp, "%d", &column);
необходимо проверить, что fp не равно NULL, чтобы бытьубедитесь, что при открытии
вам нужно проверить, что fscanf возвращает 1, чтобы убедиться, что вы смогли прочитать число
fgetc между нимибесполезно, пробел будет обойден вторым fscanf
примечанием, что вы можете сделать уникальный fscanf , чтобы прочитать два числа:
if (fscanf(fp, "%d %d", &row, &column) != 2) {
... manage error to not continue the execution
}
В
array = (int **)malloc(row * sizeof(int));
, как сказано в комментариях, вы выделяете массив int*
, а не массив int , который объясняет вашу ошибку сегментации позжев исполнении (вы явно в 64b) приведение бесполезно, поэтому array = malloc(row * sizeof(int*));
Вам также нужно проверить, что malloc не возвращает NULL
In
char tmp = fgetc(fp);
array[i][j] = (tmp - '0');
tmp должен быть int , чтобы иметь возможность проверить регистр EOF
Обратите внимание, что вы также можете читать строку, а не символ за символом
Предупреждение кр tmp получает переводы строк, поэтому вы неправильно инициализируете массив
Предложение:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
int ** array;
int row;
int column;
fp = fopen("file.path", "r");
if (fp == NULL) {
puts("cannot open file.path");
return -1;
}
if (fscanf(fp, "%d %d", &row, &column) != 2) {
puts("cannot read row column");
fclose(fp);
return -1;
}
array = malloc(row * sizeof(int*));
if (array == NULL) {
puts("not enough memory");
fclose(fp);
return -1;
}
for (int i=0; i<row; i++) {
array[i] = malloc(column * sizeof(int));
if (array[i] == NULL) {
puts("not enough memory");
fclose(fp);
return -1;
}
}
for (int i=0; i<row; i++)
{
/* finish to read previous line */
int c;
while ((c = fgetc(fp)) != '\n') {
if (c == EOF) {
fclose(fp);
puts("unexpected EOF");
return -1;
}
}
for(int j=0; j<column; j++)
{
c = fgetc(fp);
if (c == EOF) {
puts("unexpected EOF");
fclose(fp);
return -1;
}
if ((c != '0') && (c != '1')) {
puts("invalid value");
fclose(fp);
}
array[i][j] = (c - '0');
}
}
fclose(fp);
/* show the content for at least debug */
puts("array is:");
for (int i=0; i<row; i++)
{
for (int j=0; j<column; j++)
printf("%d ", array[i][j]);
putchar('\n');
}
/* free resources */
for (int i=0; i<row; i++)
{
free(array[i]);
}
free(array);
}
Компиляция и выполнение:
pi@raspberrypi:~ $ gcc -pedantic -Wextra b.c
pi@raspberrypi:~ $ cat file.path
5 5
11111
01001
00101
00010
00001
pi@raspberrypi:~ $ ./a.out
array is:
1 1 1 1 1
0 1 0 0 1
0 0 1 0 1
0 0 0 1 0
0 0 0 0 1
pi@raspberrypi:~ $
Выполнение под valgrind :
pi@raspberrypi:~ $ valgrind ./a.out
==4841== Memcheck, a memory error detector
==4841== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4841== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4841== Command: ./a.out
==4841==
array is:
1 1 1 1 1
0 1 0 0 1
0 0 1 0 1
0 0 0 1 0
0 0 0 0 1
==4841==
==4841== HEAP SUMMARY:
==4841== in use at exit: 0 bytes in 0 blocks
==4841== total heap usage: 9 allocs, 9 frees, 5,592 bytes allocated
==4841==
==4841== All heap blocks were freed -- no leaks are possible
==4841==
==4841== For counts of detected and suppressed errors, rerun with: -v
==4841== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
Примечание: я использую fscanf затем fgetc и из-за смеси необходимо управлятьnewline, другой способ - всегда использовать getline для чтения строки в строке и для dims для использования sscanf