2016-02-29 1 views
0

Извините, если этот вопрос был спрошен Я искал этот сайт на пару часов и еще ничего не видел.C программы. Взяв верхнее число из входного файла, создав 2d-массив, а затем прочитав сетку из файла

Так что я читаю входной файл, который выглядит так. Верхняя строка представляет собой массив 8x8 2d, а затем оставшиеся строки, которые я должен сортировать. В основном я заменяю каждую * буквой +1, поэтому a, b, c ... и т. Д., Но это не мой вопрос.

8 <---- The size of the array 8X8 
**......  
**..*..* 
..**.**. 
..**..*. 
.*..*..* 
..**.**. 
..**.**. 
.*..*..* 

мой вопрос, как я могу прочитать только в верхней строке входного файла, чтобы найти размер массива, то хранить, что в качестве строки и столбцов моего массива, а затем прочитать оставшуюся часть файла (сетка) и сохранить символы в строках и столбцах массива?

Это то, что у меня есть до сих пор.

#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h> 
#include<stdlib.h> 
#define N 9 

void blobchecker(char[][N]); 

main() 
{ 
    FILE *fp; 
    fp = fopen("blobfile.txt", "r"); 
    if ((fp = fopen("blobfile.txt", "r")) == NULL) 
     printf("File not read \n"); 

    int c; 
    char myarray[N][N]; 
    int i, j; 

    fscanf(fp, "%d", &c); 
    fclose(fp); 
    fp = fopen("blobfile.txt", "r"); 
    for (i = 0; i < N; i++) 
     for (j = 0; j < N; j++) 
      fscanf(fp, "%c", &myarray[i][j]); 

    for (i = 0; i < N; i++) 
     for (j = 0; j < N; j++) 
      printf("%c", myarray[i][j]); 

    printf("\n Now checking for blobs \n"); 

    // blobchecker(myarray); 

    fclose(fp); 
} 
+2

Несвязанное примечание, но если вы не можете открыть файл, это бы не фатальная ошибка? После этого вы не сможете продолжить, особенно не продолжайте читать и читать. Кроме того, почему вы закрываете и снова открываете файл? Это приведет к тому, что ваш код будет несовместим с данными в файле, поскольку первым символом, который вы читаете в циклах, является размер массива. Вы также не обрабатываете новые строки. –

+1

Что касается вашей проблемы, укажите 'myarray' * после *, вы читаете размер. C поддерживает [массивы переменной длины] (http://en.wikipedia.org/wiki/Variable-length_array). –

ответ

2

Попробуйте это:

int c; 
char** myarray; 
int i; 
fscanf(fp, "%d", &c); 
myarray = malloc(c*sizeof(char*)); 
for (i=0; i<c; i++) 
    myarray[i] = malloc(c); 

И не забудьте освободить выделенную память на более позднем этапе выполнения вашей программы:

for (i=0; i<c; i++) 
    free(myarray[i]); 
free(myarray); 
+0

Чтобы избежать проблем, вызванных символом новой строки, добавьте пробел перед '% c':' fscanf (fp, "% c", & myarray [i] [j]); ' – MikeCAT

+0

Любая причина, по которой вы рекомендуете OP не использовать 2D массив? В коде нет ничего, что указывало бы на то, что он использует эту таблицу поиска, которую вы разместили. – Lundin

+0

@ Lundin: Привет. Снова - та же проблема, что и в прошлый раз ... Как бы вы порекомендовали реализовать это с использованием динамического распределения (и, конечно, использовать '[] []')? –

2

Вот решение без используя выделенную кучу память. Примечание. Это решение работает только со стандартными и последующими версиями C99.

int main() 
{ 
    FILE *fp; 
    fp = fopen("blobfile.txt", "r"); 
    if ((fp = fopen("blobfile.txt", "r")) == NULL) { 
     printf("File not read \n"); 
     return 1; // end the program when the file can't be opened 
    } 

    int c; 
    int i, j; 

    fscanf(fp, "%d", &c); 

    char myarray[c][c]; // variable length array using the read size 

    for (i = 0; i < c; i++) // use c as upper limit 
     for (j = 0; j < c; j++) 
      fscanf(fp, " %c", &myarray[i][j]); 

    for (i = 0; i < c; i++) 
    { 
     for (j = 0; j < c; j++) 
      printf("%c", myarray[i][j]); 
     printf("\n"); 
    } 
    printf("\n Now checking for blobs \n"); 

    //blobchecker(myarray); 

    fclose(fp); 

} 

Ваша проблема заключалась в открытии и повторном открытии файла после того, как вы прочли размер массива. Открыв файл снова, вы сбросите «курсор» (индикатор позиции потока) в начало файла. Итак, первый символ, который вы прочитали, был размером вашего массива.

+1

В то время как VLA (массивы переменной длины) поддерживаются в C99, вопрос помечен * c * (другими словами, ваш предлагаемый код не обязательно будет компилироваться). –

+0

@barakmanos Я отредактировал ответ, чтобы отметить, что это C99 solutiion. – muXXmit2X

+0

@ muXXmit2X Нет необходимости в этом, ваш ответ был в порядке, так как это было, barak manos просто путают использование тега C. Согласно викторике тегов C, предполагается, что все вопросы в теге C используют текущий стандарт ISO, который находится на этом этапе 9899: 2011. Если OP интересуется устаревшими версиями C, им необходимо явно указать свой вопрос K & R, C90 или C99. – Lundin

0

Динамически выделять память с использованием malloc и free после ее использования.

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h> 
#include <stdlib.h> 
/* `#define N 9` Not needed */ 

void blobchecker(char**); /* Note the change here */ 

int main(void) /* Always use a standard signature of main */ 
{ 

    /* Indent your code properly always */ 

    FILE *fp; 
    fp = fopen("blobfile.txt", "r"); 
    if ((fp = fopen("blobfile.txt", "r")) == NULL) 
    { 
     /* `printf("File not read \n");` Better to print in stderr */ 
     fputs("Failed to open file 'blobfile.txt'", stderr); 
     return EXIT_FAILURE; /* Exit the program (main) */ 
    } 


    int c; 
    /* char myarray[N][N]; */ 
    char **myarray; /* Note the change here */ 
    int i, j; 

    fscanf(fp, "%d", &c); 

    /* 
    `fclose(fp);` 
    `fp = fopen("blobfile.txt", "r");` Don't close and reopen 
    */ 

    myarray = malloc(c * sizeof *myarray); /* Allocate `c` rows */ 
    if(NULL == myarray) /* If `malloc` failed */ 
    { 
     fputs("Failed to malloc 'myarray'", stderr); 
     return EXIT_FAILURE; /* Exit the program (main) */ 
    } 
    for (i = 0; i < c; i++) 
    { 
     myarray[i] = malloc(c); /* For each row, allocate `c` columns */ 
     if(NULL == myarray[i]) /* If `malloc` failed */ 
     { 
      for(j = i - 1; j >= 0; j--) /* `free` all previously allocated memory */ 
       free(myarray[j]); 
      free(myarray); 
      fputs("Failed to malloc 'myarray[i]'", stderr); 
      return EXIT_FAILURE; /* Exit the program (main) */ 
     } 
    } 

    for (i = 0; i < c; i++) 
     for (j = 0; j < c; j++) 
      fscanf(fp, " %c", &myarray[i][j]); /* Space before `%c` gets rid of whitespaces */ 

    for (i = 0; i < c; i++) 
     for (j = 0; j < c; j++) 
      printf("%c", myarray[i][j]); 

    printf("\n Now checking for blobs \n"); 

    //blobchecker(myarray); 

    fclose(fp); 

    /* `free` whatever you've allocated after its use: */ 

    for (i = 0; i < c; i++) 
     free(myarray[i]); 
    free(myarray); 

    return EXIT_SUCCESS; /* Exit main */ 

} 

ВНИМАНИЕ: Непроверенные код


Обратите внимание, что в приведенном выше коде, каждый вызов malloc может выделить память, не смежно, и это приведет к фрагментации кучи и снижение КПД программа. @ В комментариях Лундина упоминается об этом больше.

+0

Любая причина, по которой вы рекомендуете OP не использовать 2D-массив? В коде нет ничего, что указывало бы на то, что он использует эту таблицу поиска, которую вы разместили. – Lundin

+1

@ Lundin Вы имеете в виду VLA, верно? Это потому, что они доступны только на C99 и выше. Кроме того, судя по '#define _CRT_SECURE_NO_WARNINGS', OP использует VS, и поскольку VS использует C89, он не поддерживается. Примечание. Я знаю, что в последних версиях VS есть частичная поддержка C99, но не знаю, включены ли в нее VLA. –

+0

Нет Я имею в виду 2D-массив, будь он объявлен как VLA или что-то еще.Если вы используете компилятор динозавров, вам необходимо динамически выделять ваш 2D-массив как «искаженный», «char * myarray = malloc (c * c);». Тем не менее, это истинный 2D-массив. Он не сегментируется по всей куче, а код использует его, чтобы оптимизировать, а не плохо. – Lundin

0

Если размер известен лишь в время выполнения, вы можете использовать VLA:

int c; 
fscanf(fp, "%d", &c); 

char myarray[c][c]; 

for (i = 0; i < c; i++) 
    for (j = 0; j < c; j++) 
     fscanf(fp, "%c", &myarray[i][j]); 

Если объем памяти для чтения является еси, это могло бы быть лучше, чтобы выделить 2D массив динамически, в убедитесь, что память заканчивается на куче:

char (*myarray)[c] = malloc(sizeof(char[c][c])); 
... 
free(myarray); 

Там никогда не должно быть никакой необходимости неясных char** -На просмотровых таблиц в вашем случае. Все, что они сделают, это сегментировать массив по всей куче и замедлять работу вашей программы.


EDIT

Если вы должны быть обратно совместимы с 27 лет, устаревшего стандарта C89, вы могли бы написать переносимый код, как это:

#ifndef __STDC_VERSION__ 
    #define OLD_JUNK 
#elif __STDC_VERSION__ < 199901L 
    #define OLD_JUNK 
#endif 

#ifdef OLD_JUNK 
    #define get_item(arr, x, y) (arr [(x) * (y)]) 
#else 
    #define get_item(arr, x, y) (arr[x][y]) 
#endif 

int c; 
fscanf(fp, "%d", &c); 

#ifdef OLD_JUNK 
    char* myarray = malloc(c * c); 
#else 
    char (*myarray)[c] = malloc (sizeof(char[c][c])); 
#endif 

int i, j; 
for (i = 0; i < c; i++) 
    for (j = 0; j < c; j++) 
     fscanf(fp, "%c", &get_item(myarray,i,j)); 

free(myarray); 

Я бы, однако настоятельно рекомендуем перейти на компилятор, который не использует технологию 1980-х годов. Тогда вам не придется писать уродливые решения вроде этого.

+0

В то время как VLA (массивы переменной длины) поддерживаются в C99, вопрос помечен * c * (другими словами, ваш предлагаемый код не обязательно будет компилироваться). –

+0

@barakmanos [C tag wiki, использование тегов:] (http://stackoverflow.com/tags/c/info) «Если в вопросе явно не упоминается, какая версия используемого стандарта C, предполагается, что текущая версия используется." Насколько я понимаю, так как теги языка программирования работают на SO в целом. – Lundin

+0

@barakmanos Тем не менее, это не повод для использования фрагментированного искажения вместо реального 2D-массива. В C90 вы должны написать 'char * myarray = malloc (c * c);', а затем получить доступ к этому двумерному массиву как 'myarray [i * j]'. – Lundin

1

Это было в значительной степени отвечено, но пару дополнительных примечаний: Возможно, было бы проще использовать fscanf(fp,"%s", myarray[i][]). fscanf позаботится о charline новой строки, и таким образом вы можете назначить целую строку желаемому массиву в матрице 2d. Делает чтение и обработку проще, и вы все равно можете обратиться к определенному члену массива, используя оба его индекса. Не забудьте правильно распределить память и позаботьтесь: fscanf, который позаботится о \n, добавит его в вашу строку! Но в целом это более простое решение. Также, как было сказано, избегайте закрытия и повторного открытия файла. Если вы это сделаете, вы потеряете указатель смещения, чтобы вы в основном читали файл с самого начала, что не является ни необходимым, ни необходимым.

+0

'fscanf (fp,"% s ", myarray [i] [])' не будет компилировать –

+0

"_'fscanf', который позаботится о' \ n', добавит его в вашу строку_ '' '% s' будет никогда не сканируйте и не сохраните символ пробела. –

Смежные вопросы