很抱歉,如果这个问题被问到,我已经在这个网站上看了几个小时,还没有看到任何东西。
所以我正在阅读一个看起来像这样的输入文件。顶行是一个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);
}
答案 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)
在使用后使用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
都可能会非连续地分配内存,这会导致堆碎片并降低程序的效率。 @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技术的编译器。那么你就不必写这样丑陋的解决方案了。