Newsgroup: it.comp.lang.c
Titolo: array di stringhe

Scusate il mio problema è passare un array di stringhe ad una matrice
Nella matrice devo allocare lo spazio per la matrice( puntatore a
puntatore di char) e caricare dei dati in essa nel seguente modo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int carica_tab(char **tabellone,int n_cas)
{
    FILE *file_ptr;
    char *nome="tabellone.txt";
    int i;
    file_ptr=fopen(nome,"r");
    tabellone=(char **) malloc(50 * sizeof(char *));/*alloco array di
stringhe*/
    for(i=0;i<50;i++)
    {
        tabellone[i]=(char *) malloc(31*sizeof(char));
    }
    i=0;
    if(file_ptr!=NULL)
    {
        while(!feof(file_ptr))
        {
            fscanf(file_ptr,"%s",tabellone[i]);
            i++;
        }
        printf("%s",tabellone[0]);/*in questo caso mi lascia accedere
all'array*/
        return 0;
        fclose(file_ptr);
    }
    else return 1;
}
int main(void)
{
    char **tabellone;
    int i,n_cas;
    if(carica_tab(tabellone,n_cas)==1)
    {
        printf("errore apertura file");
        system("pause");
        exit(1);
    }
    printf("%s",tabellone[0]);/*in questo caso no!!!!!!!!!!!!!!!*/
    system("pause");
    exit(1);
}
il codice chiama una funzione che dovrebbe caricare da file deiu nomi e
scriverli sull'array dopo averlo0 allocato
il problema sorge quando uso il contenuto dell'array nel main mi causa
un errore di violazione della memoria invece nella funzione no
quindi penso nn mi passi l'array come byref
Grazie in anticipo

 quindi penso nn mi passi l'array come byref
L'array stesso é passato by ref passando il suo indirizzo by val. Con
malloc però cambi proprio quel indirizzo. Visto che non ti serve
l'indirizzo che "tabellone" non contiene quando chiami la funzione, lo
potresti implementare così (ho aggiunto anche qualche controllo per
evitare dei buffer overflow):
char **carica_tab(int n_cas)
{
    FILE *file_ptr;
    char *nome="tabellone.txt";
    int i;
    file_ptr = fopen(nome,"r");
    if ( !file_ptr )
        return 0;
    /*alloco array di stringhe*/
    char **tabellone = (char **) malloc(50 * sizeof(char *));
    if ( !tabellone )
        return 0;
    for(i=0; i<50; i++)
    {
        tabellone[i]=(char *) malloc(31*sizeof(char));
        if ( tabellone[i] == NULL )
        {
            for ( int j = 0; j < i; j++ )
            {
                free( tabellone[j] );
            }
            free( tabellone );
            return 0;
    }
    i=0;
    while(!feof(file_ptr) && i < 50)
    {
        fgets( tabellone[i], 31, file_ptr );
        i++;
    }
    fclose(file_ptr);
    printf("%s",tabellone[0]);
    return 0;
}
int main(void)
{
    char **tabellone;
    int i,n_cas;
    if( !(tabellone = carica_tab(n_cas)) )
    {
        printf("errore apertura file");
        system("pause");
        /* da aggiungere: liberare la memoria che tabellone usa */
        exit(1);
    }
    printf("%s",tabellone[0]);
    system("pause");
    /* da aggiungere: liberare la memoria che tabellone usa */
    exit(1);
}
saluti,
	benjamin
-- 
Please compose your messages as plaintext,
and do not send MS Office attachments:
 
http://www.efn.no/html-bad.html
 
http://www.goldmark.org/netrants/no-word/attach.html

 quindi penso nn mi passi l'array come byref
Infatti il passaggio "by ref" non esiste in C che usa solo il passaggio
"by value". Se passi un argomento a una funzione, ne viene fatta una
copia sullo stack e la funzione lavora su quella copia. Per modificare
variabili con effetto permanente dopo la conclusione di una funzione hai
bisogno dei puntatori. Nel tuo caso, stai passando un puntatore a
puntatore a char, ma tieni conto che ne verrà fatta una copia sullo
stack e l'allocazione che fai all'interno della funzione è valida per
quella copia. All'esterno, quando la funzione è terminata, quella copia
non esiste più quindi stai facendo riferimento a una zona di memoria che
può anche non essere leggibile. Devi usare come argomento un puntatore a 
puntatore a puntatore a char e passare l'indirizzo di tebellone:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int carica_tab(char ***tabellone, int n_cas) {
    FILE  *file_ptr;
    char  *nome = "tabellone.txt";
    int   i;
    file_ptr = fopen(nome, "r");
    *tabellone = (char **)malloc(50 * sizeof(char *));
    for (i = 0; i < 50; i++) {
       (*tabellone)[i] = (char *)malloc(31 * sizeof(char));
    }
    i = 0;
    if (file_ptr != NULL) {
       while (!feof(file_ptr)) {
          fscanf(file_ptr, "%s", (*tabellone)[i]);
          i++;
       }
       printf("%s", (*tabellone)[0]);
       return 0;
       fclose(file_ptr);
    }
    else
       return 1;
}
int main(void) {
    char  **tabellone;
    int   i, n_cas;
    if (carica_tab(&tabellone, n_cas) == 1) {
       printf("errore apertura file");
       system("pause");
       exit(1);
    }
    printf("%s", tabellone[0]);
    system("pause");
    exit(1);
}
Ciao.


Ciao, scusa ma come fa a funzionare? Nel main() ed in carica_tab() la var 
'tabellone' è allocata locale ed automatica (non occupano la stessa zona di 
stack) ed inoltre in carica_tab() non viene mai (o mi sono cecato) ritornato 
altro che '0' (mai l'indirizzo contenuto in 'tabellone'). Cioè, ho come 
l'impressione che l'indirizzo di dove è stata allocata la memoria sia andato 
perso al termine di carica_tab().
Vorrei anche fare anche una domanda:
il prototipo del main() è 'int' ma non contiene istruzioni 'return'. Siccome 
so, l'exit(), essere una funzione, va forse, ora, considerata alla stregua 
del return?
Grazie anticipatamente a tutti.
Maxime 

Grazie dell'aiuto per quanto riguarda la domanda di maxime nn so se la
funzione exit() includa anche un return ma io la uso perchè mi è
imposto dal prof dell'università .