Pointers: return of pointer to array of pointers to main 
Author Message
 Pointers: return of pointer to array of pointers to main

Please can somebody help me, I am beginner!
My base structur of the program is an array of pointers, each pointer
is a pointer to an array of characters. In the file 'udat' each line
is put into the array of characters. The result of that function is
a pointer to the array of pointers and returned to main.

My problem:
In 'main' I can only read some of the arrays of characters. Why?

[ FAXF_U.C 1K ]
#include <stdio.h>
#include <malloc.h>

#define U_DNAME "udat"
#define ZEILEN_U  7

typedef char *zeig_dat[ZEILEN_U];         /* Vektor mit 7 Zeigern auf Strings */

zeig_dat *ein_lesen(char dateiname[20]);

main()
{
    zeig_dat *uzeiger;
    zeig_dat *ein_lesen();
    int k;

    uzeiger=ein_lesen(U_DNAME);
     for(k=0;k<ZEILEN_U;k++)
        printf("\n Inhalt Zeiger: %s", *(*(uzeiger)+k));
    printf("\n");

Quote:
}

zeig_dat *ein_lesen(datei)
char datei[20];
{
    FILE *dat_zeiger, *fopen();
    zeig_dat d;
    zeig_dat *a;
    int i,j;
    int z;

    for(i=0;i<ZEILEN_U;i++)
      d[i] =(char*)malloc(ZEILEN_U,sizeof(char));

    a=(zeig_dat *)malloc(sizeof(zeig_dat));
    dat_zeiger=fopen(datei,"r");
    a=&d;                         /* Adresse des Vektors festhalten */
    if (dat_zeiger == NULL)
       printf("\nDatei kann nicht ge?ffnet werden !\n\n");
    else   {
      i=j=0;
           while ((z=fgetc(dat_zeiger)) != EOF ) {
              if (z==10)  {
                 *(d[i]+j)=0;
                j=0;
                i++;
              }
              else {
                *(d[i]+j)=z;        /* jede Zeile der Datei 'udat' einem char-Vektor bergeben */
                j++;
             }
           }
    }
    fclose(dat_zeiger);
    return(a);

Quote:
}

[ UDAT < 1K ]
um11.auva.11_95.u
um11.auva.12_95.u
um11.bva.11_95.u
um11.bva.12_95.u
um11.eis.11_95.u
um11.svb.11_95.u
um11.svb.12_95.u



Tue, 08 Jun 1999 03:00:00 GMT  
 Pointers: return of pointer to array of pointers to main


        Michaela Schulz wrote on Fri, 20 Dec 1996:
[Snip]

Quote:
> My problem:
> In 'main' I can only read some of the arrays of characters. Why?

> #include <stdio.h>
> #include <malloc.h>

Non-standard include. Try including 'stdlib.h', which is standard.

Quote:

> #define U_DNAME "udat"
> #define ZEILEN_U  7

> typedef char *zeig_dat[ZEILEN_U];         /* Vektor mit 7 Zeigern auf Strings */

> zeig_dat *ein_lesen(char dateiname[20]);

> main()
> {
>     zeig_dat *uzeiger;
>     zeig_dat *ein_lesen();

This is not necessary. You already have a prototype for 'ein_lesen' in scope
(the one declared just above 'main'). Stylistic point: in German, "einlesen"
is one word, so why did you put that underscore in that function's name? Also,
a second hint: I was taught (and made quite good experiences with it) to use
verbs for procedures (Pascal terminology, in C, that'd correspond to a function
returning void) and nouns for functions. Try it out, it really helps improve
the readability of large programs.

Quote:
>     int k;

>     uzeiger=ein_lesen(U_DNAME);
>      for(k=0;k<ZEILEN_U;k++)
>    printf("\n Inhalt Zeiger: %s", *(*(uzeiger)+k));
>     printf("\n");

You declared 'main' to return an 'int' - so it would be wise to do so!

Quote:
> }

> zeig_dat *ein_lesen(datei)
> char datei[20];
> {
>     FILE *dat_zeiger, *fopen();

Again, this local declaration of 'fopen' is not necessary. Since you include
'stdio.h', a prototype is already in scope.

Quote:
>     zeig_dat d;
>     zeig_dat *a;
>     int i,j;
>     int z;

>     for(i=0;i<ZEILEN_U;i++)
>       d[i] =(char*)malloc(ZEILEN_U,sizeof(char));

This is completely bogus. Since when does 'malloc' take two arguments?

Quote:

>     a=(zeig_dat *)malloc(sizeof(zeig_dat));
>     dat_zeiger=fopen(datei,"r");
>     a=&d;                         /* Adresse des Vektors festhalten */

What's this?? You just allocated 'a', and now you're forgetting that
reference again?

Quote:
>     if (dat_zeiger == NULL)
>        printf("\nDatei kann nicht ge?ffnet werden !\n\n");

Good! You're doing at least some error checks.

Quote:
>     else   {
>       i=j=0;
>       while ((z=fgetc(dat_zeiger)) != EOF ) {
>          if (z==10)  {

Ten? What's ten? You opened your file in text mode, so simply test against
'\n' to detect an end of line.

Quote:
>             *(d[i]+j)=0;
>            j=0;
>            i++;
>          }
>          else {
>            *(d[i]+j)=z;        /* jede Zeile der Datei 'udat' einem char-Vektor bergeben */
>            j++;
>         }
>       }
>     }
>     fclose(dat_zeiger);
>     return(a);

This is a big no-no. You assigned to 'a' the address of local variable 'd'.
The value returned will be invalid in the caller of this function since 'd'
dies, vanishes, ceases to exist, when you leave 'ein_lesen'.

Quote:
> }

With the bogus malloc loop above and that return at the end, it's no wonder
this doesn't work. If we assume an upper limit of, say, 100 characters per
line, we could do it the following way:

zeig_dat *ein_lesen (char *dateiname)
{
  FILE     *datei;
  char     buffer[101]; /* We'll read into this buffer first... */
  zeig_dat *tabelle;
  int      anzahl_zeilen = 0;
  int      i;

  datei = fopen (dateiname, "r");
  if (!datei) {
    fprintf (stderr, "Kann Datei '%s' nicht oeffnen!", dateiname);
    exit (EXIT_FAILURE);
  }
  tabelle = malloc (sizeof (zeig_dat));
  if (!tabelle) {
    fprintf (stderr, "Fehler in Speicherallokation!");
    exit (EXIT_FAILURE);
  }
  for (i = 0; i < ZEILEN_U; i++)
    (*tabelle)[i] = NULL;
  /* Now the table is initialiazed */
  while (anzahl_zeilen < ZEILEN_U &&
         fgets (buffer, sizeof(buffer), datei) != NULL) {
    /* Now we have a line in the 'buffer'. Note: we don't have to worry
       about lines longer than 'buffer' is large: we excluded that in our
       preconditions! :-) Also note: since all lines are shorter than
       buffer, we'll have the terminating '\n' in the buffer, too. */
    (*tabelle)[anzahl_zeilen] = malloc (strlen (buffer) + 1);
    if (!(*tabelle)[anzahl_zeilen]) {
      fprintf (stderr, "Fehler in Speicherallokation!");
      exit (EXIT_FAILURE);
    }
    /* Now that we have allocated a line long enough to hold the contents of
       'buffer', copy the buffer into that line: (assuming you include
       <string.h>) */
    strcpy ((*tabelle)[anzahl_zeilen], buffer);
    anzahl_zeilen++;
  }
  fclose (datei);
  return tabelle;

Quote:
} /* end ein_lesen */

Treating arbitrarily long lines is not much more difficult, but since I
didn't want to clutter above simple solution, this is left as an exercise
for the reader.

Best regards,

  Thomas
----------------------------------------------------------------------
Thomas Wolf - Swiss Federal Institute of Technology - CH-1015 Lausanne

----------------------------------------------------------------------



Tue, 08 Jun 1999 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers

2. Pointer of Pointers was Pointer of arrays...

3. Returning and manipulating array/pointer from function to main

4. Pointer to function returning pointer to function returning...

5. Array of pointers, pointer to array...

6. array pointer/pointer array

7. arrays pointers array of pointers

8. Returning Pointer To Pointer From Function

9. Question about signal()/pointers to functions that return pointers to functions

10. memory leak: pointer->pointer->pointer->struct

11. memory block containing pointers, aka pointer to pointer i believe

12. pointers pointers pointers!!!

 

 
Powered by phpBB® Forum Software