
Originariamente inviata da
oregon
Non puoi risolvere senza allocare la memoria se non sai quanto è grande il file ...
Dal testo del problema, so che il file non supera le dimensioni MAX_R x MAX_C
Ecco il codice funzionante:
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_R 50
#define MAX_C 50
int main(int narg, char *argv[])
{
char mat[MAX_R][MAX_C];
/*il vettore riga mi serve per andare a*/
char riga[MAX_R];
/*op sta per operazione e sarebbe quello che tu hai chiamato "tipo" nel tuo programma*/
char op;
/*posizione invece sarebbe il numero della riga o della colonna che hai scelto di cancellare*/
int pos;
/*eff_r ed eff_c sono rispettivamente il numero di righe e colonne della matrice di caratteri letta dal file*/
int eff_r, eff_c;
int i,j;
FILE *fp;
/*flag_ciclo è una variabile che useremo per ciclare l'esecuzione del programma finche non si verificano errori o finchè l'utente non esca
dal programma*/
int flag_ciclo;
if (narg!=2)
{
printf("Numero di parametri errato. \n");
exit (1);
}
fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("Errore nell'apertura del file %s \n", argv[1]);
exit (1);
}
i = 0;
/*leggo il file puntato da fp carattere per carattere e lo immagazzino in mat[i] (questo è quello che fa la funzione fgets).
Il while si conclude quando si arriva alla fine del file*/
while (fgets(mat[i],MAX_C,fp)!=NULL)
{
i++;
}
fclose(fp);
printf("File %s letto correttamente. \n", argv[1]);
/*memorizzo nella variabile effc la lunghezza di ogni riga (nota che sottraggo 1 perchè l'ultimo carattere presente nel vettore di stringhe
mat è il terminatore di stringa '\0' che ovviamete non devo contare). Dunque effc rappresenta il numero di colonne della matrice*/
eff_c = strlen(mat[0])-1;
/*analogamente eff_r sarà il numero di righe della matrice che era memorizzato nella variabile i incrementata
durante il while precedente*/
eff_r = i;
flag_ciclo = 0;
/*tale ciclo mi serve perchè ogni volta che do il comando da tastiera, a fine esecuzione, il programma deve permettermi di digitare
ulteriori comandi (in caso ti spiego meglio a voce)*/
while(!flag_ciclo)
{
printf("Comando: ");
/*La funzione gets brutalmente legge tutta la stringa corrispondente all’assegnazione e la funzione sscanf
la scompone nei due elementi nome e valore del nome. La funzione sscanf restituisce il numero di campi che sono stati letti, in
questo caso sarebbero 2: op e pos */
gets(riga);
j = sscanf(riga,"%c %d",&op,&pos);
/*Qui ci sono due controlli per verificare che il numero di riga o di colonna sia stato immesso sulla linea di comando*/
if ((op == 'r')&&(j == 1))
{
printf("Errore riga non specificata \n");
}
else if ((op == 'c')&&(j == 1))
{
printf("Errore colonna non specificata \n");
}
else
/*Se l'utente ha inserito il comando completo verifico in quale caso mi trovo:*/
switch(op)
{
case 'x':
printf("Programma terminato senza salvataggio. \n");
return 1;
break;
case 'r':
/*se la posizione inserita supera il massimo numero di righe della matrice e/o la posizione < 1, visualizzo l'errore*/
if ((pos > eff_r)||(pos < 1))
{
printf("Errore: riga non specificata correttamente \n");
break;
}
else
{
//Rimuovi riga: copio ciclicamente riga+1 in riga e tolgo una riga totale
printf("Rimossa riga %d. La matrice contiene:\n", pos);
for (pos = pos-1; pos < (eff_r-1); pos++)
{
/*la funzione strcpy copia il contenuto di mat[pos+1] in mat[pos]. In pratica per eliminare la riga, sovrascrivo
la riga+1 in riga */
strcpy(mat[pos],mat[pos+1]);
}
/*decremento, giustamente, il numero di righe della matrice*/
eff_r--;
//Stampo la matrice dopo l'operazione
for (i = 0; i<eff_r; i++)
{
for (j = 0; j< eff_c;j++)
{
printf("%c", mat[i][j]);
}
printf("\n");
}
}
break;
case 'c':
/*al solito controllo che la posizione della colonna scelta sia una posizione ammissibile, ovvero che non superi i
limiti inferiore e superiore*/
if ((pos > eff_c)||(pos < 1))
{
printf("Errore: colonna non specificata correttamente \n");
break;
}
else
{
//Rimuovi colonna: copio ciclicamente colonna+1 in colonna e tolgo una colonna totale
printf("Rimossa colonna %d. La matrice contiene:\n", pos);
for (i = 0; i < eff_r; i++)
for (j = pos - 1; j < (eff_c-1);j++)
{
/*qui avrei potuto utilizzare anche la funzione strcpy come fatto per le righe*/
mat[i][j] = mat[i][j+1];
}
eff_c--;
//Stampo la matrice dopo l'operazione
for (i = 0; i<eff_r; i++)
{
for (j = 0; j< eff_c;j++)
{
printf("%c", mat[i][j]);
}
printf("\n");
}
}
break;
case 'q':
//Salvo il file copiando il contenuto della matrice nel file.
fp = fopen (argv[1], "w");
if (fp == NULL)
{
printf("Errore nell'apertura del file %s in scrittura \n", argv[1]);
exit (1);
}
for (i = 0; i<eff_r; i++)
{
for (j = 0; j< eff_c;j++)
{
fprintf(fp,"%c", mat[i][j]);
}
fprintf(fp,"\n");
}
fclose(fp);
printf("Il file %s e' stato salvato correttamente. \n", argv[1]);
return 1;
break;
default:
printf("Errore: comando sconosciuto \n");
}
}
return 0;
}