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
----------------------------------------------------------------------