Ciao, inizia a postare il codice che hai scritto finora, così possiamo capire il contesto e darti un aiuto più mirato.
Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature may not be available in some browsers.
Ciao, inizia a postare il codice che hai scritto finora, così possiamo capire il contesto e darti un aiuto più mirato.
double matrice[n][m];
o double (*matrice)[m];
ma se vuoi allocarla dinamicamente con i puntatori, liberare singole righe e impostarle a NULL è un'altra cosa esempio double** matrice;
#include<stdio.h>
#include<limits.h>
#include<string.h>
#include<stdlib.h>
#define N 6
#define M 5
struct nomi_file{
char IN[256];
char OUT[256];
} nomi;
int readParameters(){
printf("\nInserire nome file di input: ");
scanf("%s", nomi.IN);
unsigned x = strlen(nomi.IN);
if(x > 255 || x < 5)
return -1;
else if(nomi.IN[x-4] != '.' || nomi.IN[x-3] != 't' || nomi.IN[x-2] != 'x' || nomi.IN[x-1] != 't'){
printf("\n%d - %c%c%c%c", x, nomi.IN[x-4], nomi.IN[x-3], nomi.IN[x-2], nomi.IN[x-1]);
printf("\nChiudo");
return -1;
}
printf("\nInserire nome file di output: ");
scanf("%s", nomi.OUT);
x = strlen(nomi.OUT);
if(x > 255 || x < 5)
return -1;
else if(nomi.OUT[x-4] != '.' || nomi.OUT[x-3] != 't' || nomi.OUT[x-2] != 'x' || nomi.OUT[x-1] != 't'){
printf("\n%d - %c%c%c%c", x, nomi.IN[x-4], nomi.IN[x-3], nomi.IN[x-2], nomi.IN[x-1]);
printf("\nChiudo");
return -1;
}
return 0;
}
double *createMatrix(char *input, int n){
char *array[50];
FILE *fp = fopen(input, "r");
if(!fp){
fprintf(stderr, "\nErrore nell'apertura del file %s", input);
perror("");
}
for(unsigned short i = 0; i<n; i++){
fscanf(fp, "%s", array[1]);
printf("\n%s", array);
}
return array;
}
int main(){
readParameters();
createMatrix(nomi.IN, N);
}
double**
allocato tramite malloc
perché in base alla consegna dovrai liberare dalla memoria certe righe in base a dei calcoli e assegnarle a NULL mentre le matrici classiche sono continue in memoria e non puoi "rimuovere" una riga dal mezzo senza costruire una nuova matrice.char *array[50];
, che è un array di 50 stringhe non inizializzato, per leggere il file ma non va bene: devi convertire ogni stringa a virgola mobile separata da spazio in un double e inserirlo al posto giusto nella matrice (puoi farlo con fscanf
e formato %lf
, oppure con strtod
come ho fatto io). Ti faccio un esempio funzionante per questo step, vedrai che sarà più chiaro anche per gli step successivi.// Questa macro serve a semplificare la gestione degli errori, stampando il messaggio, chiudendo il file e liberando la memoria
#define ERRORE(str, ...) do { fprintf(stderr, str "\n", __VA_ARGS__); failure = 1; goto cleanup; } while (0)
double** createMatrix(const char* inputFile)
{
char line[256];
int len, ncol, nline = 0, failure = 0;
double d;
FILE* fp = NULL;
char *end, *p;
double** matrix = (double**)malloc(N * sizeof(double*));
if (!matrix)
ERRORE("Memoria insufficiente");
fp = fopen(inputFile, "r");
if (!fp)
ERRORE("Errore nell'apertura del file %s", inputFile);
while (!feof(fp))
{
fgets(line, sizeof(line), fp);
len = strlen(line);
if (len < 2)
continue;
ncol = 0;
matrix[nline] = (double*)malloc(M * sizeof(double));
if (!matrix[nline])
ERRORE("Memoria insufficiente");
p = line;
while (ncol < M)
{
d = strtod(p, &end);
if (p == end)
break;
if (errno == ERANGE)
ERRORE("Errore lettura valore a linea %d", nline + 1);
matrix[nline][ncol++] = d;
p = end;
}
if (ncol != M)
ERRORE("Valori mancanti a linea %d", nline + 1);
nline++;
}
#undef ERRORE
cleanup:
if (fp)
fclose(fp);
if (!failure && nline != N)
{
fprintf(stderr, "Le linee sono %d invece che %d\n", nline, N);
failure = 1;
}
if (failure && matrix)
{
for (int i = 0; i < nline; i++)
free(matrix[i]);
free(matrix);
matrix = NULL;
}
return matrix;
}
free(matrix[X]); matrix[X] = NULL;
Grazie gentilissimo. Adesso leggo con attenzione il tuo codiceNon sono sicuro di aver capito del punto C alla media tra cosa si riferisce. Comunque sia la funzione createMatrix dovrà ritornare undouble**
allocato tramitemalloc
perché in base alla consegna dovrai liberare dalla memoria certe righe in base a dei calcoli e assegnarle a NULL mentre le matrici classiche sono continue in memoria e non puoi "rimuovere" una riga dal mezzo senza costruire una nuova matrice.
Nel tuo codice hai usatochar *array[50];
, che è un array di 50 stringhe non inizializzato, per leggere il file ma non va bene: devi convertire ogni stringa a virgola mobile separata da spazio in un double e inserirlo al posto giusto nella matrice (puoi farlo confscanf
e formato%lf
, oppure constrtod
come ho fatto io). Ti faccio un esempio funzionante per questo step, vedrai che sarà più chiaro anche per gli step successivi.
C:// Questa macro serve a semplificare la gestione degli errori, stampando il messaggio, chiudendo il file e liberando la memoria #define ERRORE(str, ...) do { fprintf(stderr, str "\n", __VA_ARGS__); failure = 1; goto cleanup; } while (0) double** createMatrix(const char* inputFile) { char line[256]; int len, ncol, nline = 0, failure = 0; double d; FILE* fp = NULL; char *end, *p; double** matrix = (double**)malloc(N * sizeof(double*)); if (!matrix) ERRORE("Memoria insufficiente"); fp = fopen(inputFile, "r"); if (!fp) ERRORE("Errore nell'apertura del file %s", inputFile); while (!feof(fp)) { fgets(line, sizeof(line), fp); len = strlen(line); if (len < 2) continue; ncol = 0; matrix[nline] = (double*)malloc(M * sizeof(double)); if (!matrix[nline]) ERRORE("Memoria insufficiente"); p = line; while (ncol < M) { d = strtod(p, &end); if (p == end) break; if (errno == ERANGE) ERRORE("Errore lettura valore a linea %d", nline + 1); matrix[nline][ncol++] = d; p = end; } if (ncol != M) ERRORE("Valori mancanti a linea %d", nline + 1); nline++; } #undef ERRORE cleanup: if (fp) fclose(fp); if (!failure && nline != N) { fprintf(stderr, "Le linee sono %d invece che %d\n", nline, N); failure = 1; } if (failure && matrix) { for (int i = 0; i < nline; i++) free(matrix[i]); free(matrix); matrix = NULL; } return matrix; }
A questo punto liberare la riga X è uno scherzo:free(matrix[X]); matrix[X] = NULL;
Ti ringrazio nuovamente, ma da quel che capisco dal codice viene liberata tutta la riga della matrice, ma il testo chiede che venga impostato a NULL il singolo puntatore all'elemento, gli altri elementi della riga debbono rimanere disponibiliNon sono sicuro di aver capito del punto C alla media tra cosa si riferisce. Comunque sia la funzione createMatrix dovrà ritornare undouble**
allocato tramitemalloc
perché in base alla consegna dovrai liberare dalla memoria certe righe in base a dei calcoli e assegnarle a NULL mentre le matrici classiche sono continue in memoria e non puoi "rimuovere" una riga dal mezzo senza costruire una nuova matrice.
Nel tuo codice hai usatochar *array[50];
, che è un array di 50 stringhe non inizializzato, per leggere il file ma non va bene: devi convertire ogni stringa a virgola mobile separata da spazio in un double e inserirlo al posto giusto nella matrice (puoi farlo confscanf
e formato%lf
, oppure constrtod
come ho fatto io). Ti faccio un esempio funzionante per questo step, vedrai che sarà più chiaro anche per gli step successivi.
C:// Questa macro serve a semplificare la gestione degli errori, stampando il messaggio, chiudendo il file e liberando la memoria #define ERRORE(str, ...) do { fprintf(stderr, str "\n", __VA_ARGS__); failure = 1; goto cleanup; } while (0) double** createMatrix(const char* inputFile) { char line[256]; int len, ncol, nline = 0, failure = 0; double d; FILE* fp = NULL; char *end, *p; double** matrix = (double**)malloc(N * sizeof(double*)); if (!matrix) ERRORE("Memoria insufficiente"); fp = fopen(inputFile, "r"); if (!fp) ERRORE("Errore nell'apertura del file %s", inputFile); while (!feof(fp)) { fgets(line, sizeof(line), fp); len = strlen(line); if (len < 2) continue; ncol = 0; matrix[nline] = (double*)malloc(M * sizeof(double)); if (!matrix[nline]) ERRORE("Memoria insufficiente"); p = line; while (ncol < M) { d = strtod(p, &end); if (p == end) break; if (errno == ERANGE) ERRORE("Errore lettura valore a linea %d", nline + 1); matrix[nline][ncol++] = d; p = end; } if (ncol != M) ERRORE("Valori mancanti a linea %d", nline + 1); nline++; } #undef ERRORE cleanup: if (fp) fclose(fp); if (!failure && nline != N) { fprintf(stderr, "Le linee sono %d invece che %d\n", nline, N); failure = 1; } if (failure && matrix) { for (int i = 0; i < nline; i++) free(matrix[i]); free(matrix); matrix = NULL; } return matrix; }
A questo punto liberare la riga X è uno scherzo:free(matrix[X]); matrix[X] = NULL;
Ti ringrazio nuovamente, ma da quel che capisco dal codice viene liberata tutta la riga della matrice, ma il testo chiede che venga impostato a NULL il singolo puntatore all'elemento, gli altri elementi della riga debbono rimanere disponibili
double***
e accedere ai valori con *matrix[X][Y]
e liberarli con free(matrix[X][Y]); matrix[X][Y] = NULL;
Grazie, mi sei stato molto utile. Grazie per il tempo che mi hai dedicatoHai ragione, ho letto il testo velocemente e avevo capito fosse necessario liberare righe e non singoli valori anche perché ha ancora meno senso questa struttura dati (visto che poi copi comunque tutto in un array) ma capisco che è solo un esercizio didattico. Per fare questa matrice "con i buchi" che puoi liberarne singoli elementi puoi trasformare la matrice indouble***
e accedere ai valori con*matrix[X][Y]
e liberarli confree(matrix[X][Y]); matrix[X][Y] = NULL;