C程序。从输入文件中取最高数字,创建2d数组,然后从文件

时间:2016-02-29 06:37:34

标签: c

很抱歉,如果这个问题被问到,我已经在这个网站上看了几个小时,还没有看到任何东西。

所以我正在阅读一个看起来像这样的输入文件。顶行是一个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);
}

5 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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);

}

您的问题是在您读取数组大小后打开并重新打开文件。 再次打开文件,您可以重置“光标”。 (流位置指示器)到文件的开头。所以你读过的第一个charactar就是数组的大小。

答案 2 :(得分:1)

这已经得到了很好的回答,但还有几点注释:使用fscanf(fp,"%s", myarray[i][])可能更容易。 fscanf将处理换行符,这样就可以将整个字符串分配给2d矩阵中的所需数组。使读取和处理方式更容易,您仍然可以使用他的两个索引引用数组的特定成员。确保正确分配内存并注意:负责\n的fscanf会将其添加到您的字符串中!但总的来说,这是一个更简单的解决方案。 此外,正如所述,避免关闭并重新打开文件。如果你这样做,你就会丢失一个偏移指针,这样你就可以从顶部重新读取一个文件,这既不是必需的,也不是必需的。

答案 3 :(得分:0)

在使用后使用mallocfree动态分配内存。

#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都可能会非连续地分配内存,这会导致堆碎片并降低程序的效率。 @Lundin的评论更多地提到了这一点。

答案 4 :(得分: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**的模糊查找表。他们所要做的就是在整个堆中分割你的数组并使你的程序变慢。

修改

如果你需要向后兼容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);
但是,我强烈建议升级到不使用1980s技术的编译器。那么你就不必写这样丑陋的解决方案了。