我读了一个文本文件并将内容存储在一个名为H的2D数组中,我需要将这个2D数组以某种方式返回到main,所以我可以在那里使用它并将其传递给其他函数。我不知道如何让返回工作,也许使用指针。我将readTxtFile函数设置为void函数来测试文件读取是否正常(它确实如此)但我无法对函数外部的2D数组执行任何操作。我有两个函数getRows()和getCols(),我没有在这里显示,但我可以,如果需要的话。
到目前为止我的代码:
int main(void){
// int *H;
// H = readTxtFile("H.txt");
readTxtFile("H.txt");
return 0;
}
void readTxtFile(char *filename){
int rows, cols;
FILE *fp = fopen(filename, "r");
if (!fp){
perror("can't open H.txt\n");
//return EXIT_FAILURE;
}
rows = getRows(fp);
cols = getCols(fp);
int (*H)[cols] = malloc(sizeof(int[rows][cols]));
if(!H){
perror("fail malloc\n");
exit(EXIT_FAILURE);
}
for(int r = 0; r < rows; ++r){
for(int c = 0; c < cols; ++c){
if(EOF==fscanf(fp, "%d", &H[r][c])){
fprintf(stderr, "The data is insufficient.\n");
free(H);
exit(EXIT_FAILURE);
}
}
}
fclose(fp);
// printH(rows,cols,H);
// return H;
}
这就是文本文件的样子:
1 1 0 1 0 0
0 1 1 0 1 0
1 0 0 0 1 1
0 0 1 1 0 1
2 2 2 2 2 2
任何帮助将不胜感激
答案 0 :(得分:3)
我要做的是根据它来定义2D数组的结构:
请注意,我会&#34;线性化&#34; 数组,即分配一个大小为Columns * Rows * sizeof(int)
的内存块,并给出 i 和 j 行和列索引,这两个索引可以用简单的数学转换为1D数组中的单索引(例如index = rowIndex * Columns + columnIndex
)
然后,我只是从ReadTxtFile函数返回一个指向这个结构的指针:
struct IntArray2D {
int Rows;
int Columns;
int* Elements;
};
/*
* Define a couple of helper functions to allocate
* and free the IntArray2D structure.
*/
struct IntArray2D* IntArray2D_Create(int rows, int columns);
void IntArray2D_Free(struct IntArray2D* array);
/*
* On success, returns a 2D array with data read from file.
* On failure, returns NULL.
* NOTE: callers must call IntArray2D_Free() when done
*/
struct IntArray2D* ReadTxtFile(const char* filename);
编辑作为替代方案,你可以定义数组结构有一个带行和列的标题块,立即后跟&#34;线性化&#34 ; 2D数组元素,使用 "flexible array member" :
struct IntArray2D {
int Rows;
int Columns;
int Elements[];
};
然后,您可以定义一些方便的函数来操作此自定义数组结构,例如:
struct IntArray2D* IntArray2D_Create(int rows, int columns)
{
/* Check rows and columns parameters are > 0 */
/* ... */
struct IntArray2D *p = malloc(sizeof(struct IntArray2D)
+ rows * columns * sizeof(int));
if (p == NULL) {
return NULL;
}
p->Rows = rows;
p->Columns = columns;
/* May zero out the array elements or not... */
memset(p->Elements, 0, rows * columns * sizeof(int));
return p;
}
void IntArray2D_Free(struct IntArray2D* array)
{
free(array);
}
int IntArray2D_GetElement(struct IntArray2D* array,
int row, int column)
{
/* Check array is not NULL; check row and column
indexes are in valid ranges ... */
int index = row * (array->Columns) + column;
return array->Elements[index];
}
void IntArray2D_SetElement(struct IntArray2D* array,
int row, int column,
int value)
{
/* Check array is not NULL; check row and column
indexes are in valid ranges ... */
int index = row * (array->Columns) + column;
array->Elements[index] = value;
}
在ReadTxtFile
功能中,您可以拨打malloc
,而不是致电IntArray2D_Create
:
struct IntArray2D* ReadTxtFile(const char* filename)
{
struct IntArray2D* data = NULL;
/* ... */
rows = getRows(fp);
cols = getCols(fp);
data = IntArray2D_Create(rows, cols);
if (data == NULL) {
/* Handle error ... */
return NULL;
}
/* Fill the array ... */
特别是你的:
if(EOF==fscanf(fp, "%d", &H[r][c])){
你可以这样做:
/* int valueReadFromFile */
if (EOF == fscanf(fp, "%d", &valueReadFromFile)) {
fprintf(stderr, "The data is insufficient.\n");
}
IntArray2D_SetElement(data, r, c, valueReadFromFile);
然后在函数结束时,您可以:
return data;
}
答案 1 :(得分:0)
您无法从函数返回数组;返回指向数组的指针。
当然,您可以在任何函数(即“global”)之外创建一个数组(或指向数组的指针),并从同一模块中的任何其他函数(甚至是同一个程序)访问它使用extern
关键字),但我不建议您这样做。最好遵循第一个方法。
答案 2 :(得分:0)
一种方法是将行数和列数返回给调用者以及指向数组本身的指针(我还没有尝试编译这个......):
int main(void){
// int *H;
// H = readTxtFile("H.txt");
int rows;
int cols;
void *array;
readTxtFile("H.txt",&rows,&cols,&array);
int (*H)[*cols] = array;
/* process array here */
free(array);
return 0;
}
void readTxtFile(char *filename, int *rows, int *cols, void **array ){
int rows, cols;
FILE *fp = fopen(filename, "r");
if (!fp){
perror("can't open H.txt\n");
//return EXIT_FAILURE;
}
*rows = getRows(fp);
*cols = getCols(fp);
int (*H)[cols] = malloc(sizeof(int[*rows][*cols]));
if(!H){
perror("fail malloc\n");
exit(EXIT_FAILURE);
}
for(int r = 0; r < rows; ++r){
for(int c = 0; c < cols; ++c){
if(EOF==fscanf(fp, "%d", &H[r][c])){
fprintf(stderr, "The data is insufficient.\n");
free(H);
exit(EXIT_FAILURE);
}
}
}
fclose(fp);
/* cast is not necessary - added to clearly indicate that the
pointer returned carries no row/column information with it */
*array = ( void * ) H;
}
@ Mr.C64&#39的回答基本上是一样的,我认为这是一种更清洁的方式。