2016-03-04 22 views
2

以下代码获取从在一维阵列中的文件并将其存储输入。我想输入的像的矩阵式:转换数组大小

1,2,4 
3,4,5 
5,6,7 

(或)

2,3,4,5 
4,5,6,7 
7,6,5,4 
3,4,5,6 

其中矩阵的大小而变化,并且它们由逗号分隔的,要被存储在2D阵列。我应该对下面的代码做些什么改变?

#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
    char file[51]; 
    int data, row, col, c, count, inc; 
    int *array, capacity=50; 
    char ch; 
    array = (int*)malloc(sizeof(int) * capacity); 
    printf("\nEnter the name of the file with its extention\n"); 
    scanf("%s", file); 
    FILE *fp = fopen(file, "r"); 
    row = col = c = count = 0; 
    while (EOF != (inc = fscanf(fp,"%d%c", &data, &ch)) && inc == 2){ 
     ++c; //COLUMN count 
     if (capacity == count) 
      array = (int*)realloc(array, sizeof(int) * (capacity *= 2)); 
     array[count++] = data; 
     if(ch == '\n'){ 
      ++row; 
      if (col == 0){ 
       col = c; 
      } else if (col != c){ 
       fprintf(stderr, "format error of different Column of Row at %d\n", row); 
       goto exit; 
      } 
      c = 0; 
     } else if (ch != ',') { 
      fprintf(stderr, "format error of different separator(%c) of Row at %d \n", ch, row); 
      goto exit; 
     } 
    } 
    { //check print 
     int i, j; 
     //int (*matrix)[col] = array; 
     for(i = 0; i < row; ++i){ 
      for(j = 0; j < col; ++j) 
       printf("%d ", array[i * col + j]);//matrix[i][j] 
      printf("\n"); 
     } 
    } 
exit: 
    fclose(fp); 
    free(array); 
    return 0; 
} 
+4

他们说[你不应该在C]中抛出'malloc()'的结果(http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – MikeCAT

+1

进行的更改之一:向内存分配和文件打开添加错误检查。 – MikeCAT

+0

谢谢你。更改记录。 – Raj

回答

0

只需保存并读取数组总是一个单一维度的字符串,其长度是所有维度乘以该类型的大小的乘积。然后返回一个指向void的指针,该指针将被分配给指向所需维数组的指针。
I.e.

void *MyReadFnc(char *filename, size_t size) 
{ 
    char *p = malloc(size); 
    //open file and load the data 
    return (void *)p; 
} 
... 
//Call the function to read in our array. 
//For who don't see it we want assign to an array of 5 dimensions 
//array[10][2][3][4][5] 
//Note that the first dimension is omitted, but we have to use it in array size calcullation 
int (*array)[2][3][4][5] = MyReadFnc("Filename.ext", 2*3*4*5*10*sizeof(int)); 
... 
printf("element[9][1][2][3][4] = %d\n", array[9][1][2][3][4]); 
... 
//Again an array of 3 dimensions: 
//array2[10][20][30] 
int (*array2)[20][30] = MyReadFnc("Filename.ext", 20*30*10*sizeof(int)); 
... 
printf("element[9][19][29] = %d\n", array[9][19][29]); 

我们使用void *作为输出,这是因为常规是通用的,并能处理任何一个阵列(的任意维数)。而使用void *仅仅是C语言的标准和自然的方式来处理这种类型的杂色。这是方式C语言工作。如果你想要更强大的类型检查,你应该改变语言。
以下是用于读取阵列的更多的通用代码。

#include <stdio.h> 
#include <stdlib.h> 

//Because we read whole data as single stream like a 1 dimension array, totElems 
//is the total number of elements expressed as the product of all dimensions of 
//the final array 
void *ReadArray(char *fname, size_t totElems, size_t ElemSize) 
{ 
    FILE *fp = fopen(fname, "r"); 
    if (!fp) 
    { 
     fprintf(stderr, "Can't open file <%s>\n", fname); 
     exit(-1); 
    } 

    int *p = calloc(totElems, ElemSize); 
    if (!p) 
    { 
     fprintf(stderr, "Can't allocate memory\n"); 
     exit(-1); 
    } 

    for (size_t i=0; ; i++) 
    { 
     int a; 

     if (EOF==fscanf(fp, "%d,", &a)) 
      break; 
     p[i] = a; 
    } 

    fclose(fp); 
    return (void *)p; 
} 

int main(void) 
{ 
    char file[51]; 
    printf("\nEnter the name of the file with its extention\n"); 
    scanf("%s", file); 

    printf("Array 4x4\n"); 
    //First sample: declare a pointer to a 2 dimension array 4x4 elements 
    int (*array)[4]; 
    array = ReadArray(file, 16, sizeof(int)); 
    for (int i=0; i<4; i++) 
    { 
     for(int j=0; j<4; j++) 
      printf("%d,", array[i][j]); 
     printf("\n"); 
    } 

    printf("Array 2x8\n"); 
    //Second sample: declare a pointer to a 2 dimension array 2x8 elements 
    int (*array2)[8]; 
    array2 = ReadArray(file, 16, sizeof(int)); 
    for (int i=0; i<2; i++) 
    { 
     for(int j=0; j<8; j++) 
      printf("%d,", array2[i][j]); 
     printf("\n"); 
    } 

    printf("Array 2x2x4\n"); 
    //Third sample: declare a pointer to a 3 dimension array 2x2x4 elements 
    int (*array3)[2][4]; 
    array3 = ReadArray(file, 16, sizeof(int)); 
    for (int i=0; i<2; i++) 
    { 
     for(int j=0; j<2; j++) 
     { 
      if(j) printf (" - "); 
      for (int k=0; k<4; k++) 
       printf("%d,", array3[i][j][k]); 
     } 
     printf("\n"); 
    } 

    return 0; 
} 

您可以将结果分配给任何维度的数组;)。不需要转换,因为数组对象返回为void *以实现最大的灵活性。还要注意,因为任何C数组都是数组等数组的数组,所以它实际上是与尺寸无关的。什么是该函数返回是一个数组,可以适应任何定义尊重2分的权利要求:1.所述阵列是具有ElemSize中指定的相同的sizeof(这里为了简单起见被硬连线到int)的类型,2产物整个尺寸是<=totElems
当然,这仅仅是作为基地,以开发更复杂的版本的样本,了良好的发展,可以使其能够处理任何类型的数据(不仅INT)。我相信这对于初学者来说是一个很好的练习,需要一个起点来改善自己,扩大他们的创造力。
最后只考虑在C99-C11兼容编译器,你可以这样写: 的printf(“阵列2x2x4使用变量的\ n”);

//Fourth sample: declare a pointer to a 3 dimension array 2x2x4 elements 
//using variables for dimensions 
int x = 2; 
int y = 2; 
int z = 4; 
int (*array4)[y][z]; 
array4 = ReadArray(file, 16, sizeof(int)); 
for (int i=0; i<x; i++) 
{ 
    for(int j=0; j<y; j++) 
    { 
     if(j) printf (" - "); 
     for (int k=0; k<z; k++) 
      printf("%d,", array4[i][j][k]); 
    } 
    printf("\n"); 
} 
+0

1)不要使用幻数。它们是问题的保证2)直接的方法是始终使用指针指向的对象'sizeof':sizeof(* array)':没有冗余,您不必考虑正确的类型(当然,你仍然会乘以外部尺寸)。 – Olaf

+0

查看维基百科:https://zh.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants – Olaf

+0

@Olaf仍然不明白。这些数字是用户数组的任意维数而不是幻数。在引用与编译器相关的唯一一个参数时,没有悬挂的数字是'sizeof(int)'。 –

0

好的,你现在的代码已经知道如何确定第一行结尾的列数,并控制所有行的列数相同。

您可以在第一行的末尾分配一个二维数组方式:

capacity = cols * cols; 
int (* arr)[cols] = malloc(sizeof(int) * capacity); // array is a 2D array cols x cols 

(当然,你必须存储在另一个阵列的第一行,你必须复制在新分配的数据ARR ...)

然后您分配方式:

arr[row][c] = data; 

唯一的要求是,你的编译器接受变长数组。它是在C99中指定的,但一些旧的MS编译器(至少到2008年)不接受它。