2016-04-25 4 views
0

Ich bekomme einen Segmentierungsfehler, wenn ich versuche, meinen Code auszuführen, um eine Datendatei in ein 2D-Array zu lesen. Ich bin mir nicht sicher, ob ich das Array nicht richtig übergebe oder die Datei richtig in das Array lese.Segmentierungsfehler nach dem Lesen einer Datendatei in ein 2D-Array

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

void two_D_input(FILE *fp, int **arr, int* r, int* c) 
{ 
     size_t count; 
     char *line = malloc(20); 
     while(getline(&line, &count, fp) != 1) { 
       for(; count > 0; count--, *c++) 
         sscanf(line, "%d", *&arr[*r][*c]); 
       *r++; 
     } 
} 

main() 
{ 
     int a, b, i, j; 
     int* array[10][10]; 
     FILE *f; 
     f = fopen("test", "r"); 
     two_D_input(f, &array[0][0], &i , &j); 
     for(a =0; a < i; a++){ 
       for(b=0;b<j; b++){ 
         printf("\n%d", array[a][b]); 
       } 
     } 
     fclose(f); 
} 

Der Dateitest sieht jetzt so aus.

1 0 
1 1 
+0

Wo genau schlägt Ihr Code fehl? Wäre es nicht einfacher, 'fscanf' zu verwenden, um die Zahlen direkt aus der Datei zu extrahieren? – Fjotten

+1

Der 'int ** arr', den Sie in Ihrer Funktion haben, ist nicht mit dem' int * -Array [10] [10] 'im Aufrufer kompatibel. –

+1

Auch haben Sie Probleme mit der Art, wie 'r' und' c' initialisiert werden. –

Antwort

0

Änderung wie folgt aus:

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

void two_D_input(FILE *fp, int arr[][10], int *r, int *c){ 
    size_t count = 0; 
    char *line = NULL; 

    *r = *c = 0; 
    while(getline(&line, &count, fp) != -1) { 
     char *readPos = line; 
     int readLen = 0, col = 0; 
     while(col < 10 && 1==sscanf(readPos, "%d%n", &arr[*r][col], &readLen)){ 
      readPos += readLen; 
      ++col; 
     } 
     *c = col;//It is necessary all the same number of columns 
     ++*r;//or (*r)++; 
    } 
    free(line); 
} 

int main(void){ 
    int a, b, i, j; 
    int array[10][10]; 
    FILE *f; 

    f = fopen("test", "r"); 
    two_D_input(f, array, &i , &j); 
    for(a = 0; a < i; a++){ 
     for(b = 0; b < j; b++){ 
      printf("%d ", array[a][b]); 
     } 
     putchar('\n'); 
    } 
    fclose(f); 

    return 0; 
} 
+0

Furchtsam, wie nahe diese waren. –

+0

Ich habe die Anzahl der Zeilen vergessen. – BLUEPIXY

+1

Ja, aber es hat Spaß gemacht, all die anderen Ähnlichkeiten zu sehen. Ich hatte einen früheren Termin, habe mich dann ein wenig mit der Antwort beschäftigt und dann haben wir beide innerhalb einer Minute gepostet. Jenseits des Timings, denke ich, gibt es tatsächlich ein paar Standardmethoden in C, weil der Kern der Lösungen fast identisch ist. –

2

Es dauerte ein wenig zu verstehen, was Sie zu tun versuchen. Wenn ich richtig verstehe, wollen Sie ein statisches Array von M x N Größe zu erklären, und dann haben two_D_input zu M x N Elemente füllen Rückkehr der eigentlichen Reihe und col über Zeiger gefüllt Werte r und c.

Es ist nichts falsch daran, dies zu tun, aber Sie müssen das Lesen (oder Initialisieren) der gleichen Anzahl von Spalten pro Zeile erzwingen, so dass der Wert für die Anzahl der gelesenen Spalten nicht auf nicht initialisiert zeigt Werte. Sie müssen sich auch davor schützen, über die Grenzen Ihres Arrays gelesen zu werden.

Während Sie jede Zeile von Daten mit getline vor Parsen jede Zeile von Daten in Integer-Werte lesen können, ist es nur ein einfach einen statisch erklärten Puffer und fgets in two_D_input zu verwenden. (Es entfällt auch die Notwendigkeit, free die von getline zugewiesenen Speicher)

Putting alle Teile zusammen, können Sie Sie two_D_input Funktion wie die folgende schreiben:

enum { NROW = 10, NCOL = 10, MAXC = 256 }; 
... 
void two_D_input (FILE *fp, int (*arr)[NCOL], int *r, int *c) 
{ 
    char buf[MAXC] = "";   /* temp buffer to hold line */ 
    int tmp = 0, tmpc = 0;  /* temp int and column val */ 
    *r = *c = 0;     /* initialize row, col ptrs */ 

    while (fgets (buf, MAXC, fp)) {  /* read line into buf */ 
     char *p = buf; 
     int n = 0; /* read int into tmp, get offset in buf */ 
     while (tmpc < NCOL && sscanf (p, " %d%n", &tmp, &n) == 1) 
     {   /* while cols < NCOL & value read from buf */ 
      arr[*r][tmpc++] = tmp;  /* assign array value */ 
      if (tmpc > *c) *c = tmpc; /* update colum width */ 
      p += n;     /* update p for next read */ 
     } 
     if (*c != tmpc) { 
      fprintf (stderr, "error: invalid column count.\n"); 
      exit (EXIT_FAILURE); 
     } 
     (*r)++, tmpc = 0;   /* increment row, reset col */ 
     if (*r == NROW)   /* check against max row val */ 
      break; 
    } 
} 

(vergessen Sie nicht, (*r)++ erhöht die Wert, auf den r, erhöht *r++ den Zeiger r

setzen sie alle zusammen Sie so etwas wie das folgende tun könnte.

#include <stdio.h> 
#include <stdlib.h> /* for exit */ 

enum { NROW = 10, NCOL = 10, MAXC = 256 }; 

void two_D_input (FILE *fp, int (*arr)[NCOL], int *r, int *c) 
{ 
    char buf[MAXC] = "";   /* temp buffer to hold line */ 
    int tmp = 0, tmpc = 0;  /* temp int and column val */ 
    *r = *c = 0;     /* initialize row, col ptrs */ 

    while (fgets (buf, MAXC, fp)) {  /* read line into buf */ 
     char *p = buf; 
     int n = 0; /* read int into tmp, get offset in buf */ 
     while (tmpc < NCOL && sscanf (p, " %d%n", &tmp, &n) == 1) 
     {   /* while cols < NCOL & value read from buf */ 
      arr[*r][tmpc++] = tmp;  /* assign array value */ 
      if (tmpc > *c) *c = tmpc; /* update colum width */ 
      p += n;     /* update p for next read */ 
     } 
     if (*c != tmpc) { 
      fprintf (stderr, "error: invalid column count.\n"); 
      exit (EXIT_FAILURE); 
     } 
     (*r)++, tmpc = 0;   /* increment row, reset col */ 
     if (*r == NROW)   /* check against max row val */ 
      break; 
    } 
} 

int main (int argc, char **argv) 
{ 
    int array[NROW][NCOL] = {{0}}; 
    int i, j, r = 0, c = 0; 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 
    if (!fp) { 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    two_D_input (fp, array, &r, &c); 
    printf ("\n read (%d x %d) array\n\n", r, c); 

    if (fp != stdin) 
     fclose (fp); 

    for (i = 0; i < r; i++) { 
     for (j = 0; j < c; j++) printf (" %2d", array[i][j]); 
     putchar ('\n'); 
    } 

    return 0; 
} 

Beispiel Eingabedateien

$ cat dat/a2d.txt 
1 0 
1 1 

$ cat ../dat/10by10.txt 
0 1 2 3 4 5 6 7 8 9 
10 11 12 13 14 15 16 17 18 19 
20 21 22 23 24 25 26 27 28 29 
30 31 32 33 34 35 36 37 38 39 
40 41 42 43 44 45 46 47 48 49 
50 51 52 53 54 55 56 57 58 59 
60 61 62 63 64 65 66 67 68 69 
70 71 72 73 74 75 76 77 78 79 
80 81 82 83 84 85 86 87 88 89 
90 91 92 93 94 95 96 97 98 99 

Beispiel Verwendung/Output

$ ./bin/a2dfscanf <dat/a2d.txt 

read (2 x 2) array 

    1 0 
    1 1 

$ ./bin/a2dfscanf <../dat/10by10.txt 

read (10 x 10) array 

    0 1 2 3 4 5 6 7 8 9 
10 11 12 13 14 15 16 17 18 19 
20 21 22 23 24 25 26 27 28 29 
30 31 32 33 34 35 36 37 38 39 
40 41 42 43 44 45 46 47 48 49 
50 51 52 53 54 55 56 57 58 59 
60 61 62 63 64 65 66 67 68 69 
70 71 72 73 74 75 76 77 78 79 
80 81 82 83 84 85 86 87 88 89 
90 91 92 93 94 95 96 97 98 99 

schauen Sie vorbei und lassen Sie mich wissen, wenn Sie Fragen haben.