Linguaggio C, file e array di caratteri

di il
8 risposte

Linguaggio C, file e array di caratteri

Ciao!

Questa volta l'esercizio è:


Realizzare un programma C che legge il contenuto di un file carattere per carattere (inclusi gli spazi bianchi ed i caratteri di ritorno a capo) e lo memorizza in un array di lunghezza opportuna. quindi implementare la funzione:

- char* codifica(const char* s, int d) che, data una stringa s ed un intero d, restituisce una nuova stringa il cui codice ASCII del carattere i-esimo è ottenuto sottraendo d al codice dell'i-esimo carattere di s.

Verificare la funzione mediante un'opportuna funzione main di prova.


Dunque, ecco il main:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "codifica.h"

int main()
{
	FILE *f = fopen("/home/davide/Scrivania/Esercitazione 3/testo.txt", "r");
	
	char flag, *s;
	int i = 0, d;
	
	if(f == NULL) printf("Errore nell'apertura del file.\n");
	else
	{
		//Ciclo per contare quanti caratteri 
		//ci sono all'interno del file, in modo tale
		//da definire la lunghezza dell'array
		//da allocare dinamicamente
		while(!feof(f))
		{
			flag = getc(f);
			i++;
		}
		
		i--;
		printf("%d", i);
		
		//Allocazione dinamica della stringa
		s = (char *) malloc (i * sizeof(char));
		
		//Inserimento dei dati all'interno della stringa
		i = 0;
		while(!feof(f))
		{
			fscanf(f, "%c", &s[i]);
			i++;
		}
		
		for( i = 0; i < 5; i++)
			printf("s[%d] = %c\n", i, s[i]); 
		
		//Inserimento di d
		//printf("d: ");
		//scanf("%d", &d);
		
		//Invocazione della funzione codifica
		codifica(s, d);
		
		fclose(f);
	}
	return 0;
} 
1 - All'interno del ciclo:

	while(!feof(f))
		{
			flag = getc(f);
			i++;
		}
Ci ho dovuto mettere, per forza, la prima istruzione che vedete, perché altrimenti i non mi acquisisce niente. Perché?

2 - All'interno di:
		
for( i = 0; i < 5; i++)
     printf("s[%d] = %c\n", i, s[i]);
Mi stampa un array vuoto (ho messo 5 perché ho "a b c" all'interno del file), perché?

---

Una volta sistemati questi due punti:

3 - Perché l'array, nella definizione della funzione codifica, l'esercizio me lo dichiara di tipo const? Qual è la necessità?
4 - Una volta passato l'array, devo chiaramente scandirlo elemento per elemento per poterlo codificare, ma come faccio a farlo se nella funzione non passo la dimensione dell'array?
5 - Per la codifica avevo pensato ad una cosa del genere:

codifica.c

#include <stdio.h>
#include <string.h>

#include "codifica.h"

char* codifica(const char* s, int d)
{
	int j; //Indice di scorrimento per la stringa passata alla funzione
	char temp;
	
	for(j = 0; j < (?)dimensione(?); j++)
   {
		temp = s[j];
		(int) temp;
		temp -= d;
		(char) temp;
		s[j] = temp;
	}
}
Potrebbe funzionare?

Vi ringrazio.

8 Risposte

  • Re: Linguaggio C, file e array di caratteri

    Ci ho dovuto mettere, per forza, la prima istruzione che vedete
    DI quale istruzione parli?
    Mi stampa un array vuoto
    Quando leggi il file per la seconda volta devi riportare il puntatore all'inizio con la funzione fseek oppure chiudere e riaprire il file.
    3
    Perché la funzione non deve modificare l'array passato.
    4
    Dopo la lettura, alla fine dell'array devi prevedere un altro elemento (occhio alla malloc) in cui memorizzare un carattere a 0 binario (NUL) per indicare la fine della stringa. Questo carattere ti servirà per capire quando termina il ciclo (usando una while).
    5
    Non va bene per questi motivi

    a) modifichi l'array sorgente, cosa espressamente vietata dal const

    b) non allochi un altro array in cui copi il primo modificato

    c) non restituisci il puntatore al nuovo array
  • Re: Linguaggio C, file e array di caratteri

    DI quale istruzione parli?
    Scusa, mi riferivo all'assegnamento: flag = getc(f);

    Ho provato a toglierlo dal ciclo while, e la variabile i non mi prende alcun valore. Come mai?
    Perché la funzione non deve modificare l'array passato.
    Ah ok! Mi sono accorto ora, rileggendo l'esercizio, che c'è scritto: "restituisce una nuova stringa".

    Quando leggi il file per la seconda volta devi riportare il puntatore all'inizio con la funzione fseek oppure chiudere e riaprire il file.
    Dopo
    		while(!feof(f))
    		{
    			fscanf(f, "%c", &s[i]);
    			i++;
    		}
    Ho provato a mettere:
    
    fclose(f);
    FILE *f = fopen("/home/davide/Scrivania/Esercitazione 3/testo.txt", "r");
    
    Oppure:
    fseek(f, 0, 0);
    Ma nessuna delle due funziona, dove sbaglio?

    Per quanto riguarda la conversione che mi consigli? Grazie
  • Re: Linguaggio C, file e array di caratteri

    La getc è necessaria per leggere i caratteri dal file, altrimenti come li conti?
    Potevi usare la fscanf come hai fatto nel secondo ciclo.

    La fseek va prima del ciclo che hai indicato non dopo.
  • Re: Linguaggio C, file e array di caratteri

    Ok, credo di aver fatto.
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "codifica.h"
    
    char* codifica(const char* s, int d)
    {
    	int i = 0; //Indice di scorrimento per la stringa passata alla funzione
    	int dim; //Dimensione della nuova stringa
    	char temp; //Variabile di comodo per la conversione
    	char *str; //Nuova stringa
    	
    	//Serve per acquisire la dimensione
    	//della stringa per poi allocarne una
    	//nuova dinamicamente
    	while(s[i] != '\0')
    		i++;
    	
    	dim = i;
    	
    	str = (char*)malloc(i*sizeof(char));
    	
    	//Copia dei dati nella nuova stringa
    	for(i = 0; i < dim; i++)
    		str[i] = s[i];
    
    	for(i = 0; i < dim; i++)
    	{
    		temp = str[i];
    		(int) temp;
    		temp -= d;
    		(char) temp;
    		str[i] = temp;
    	}
    	
    	for(i = 0; i < dim; i++)
    		printf("str[%d] = %c\n", i, str[i]);
    }
    L'unica cosa che non mi convince è:
    	
    for(i = 0; i < dim; i++)
    	{
    		temp = str[i];
    		(int) temp;
    		temp -= d;
    		(char) temp;
    		str[i] = temp;
    	}
    
    Nel file ho messo: "a b c";

    E, alla fine, con:
    	for(i = 0; i < dim; i++)
    		printf("str[%d] = %c\n", i, str[i]);
    
    Mi stampa:

    str[0] = `
    str[1] =
    str[2] = a
    str[3] =
    str[4] = b


    A str[1] e str[3] viene visualizzato un quadratino con all'interno "001F". ?
  • Re: Linguaggio C, file e array di caratteri

    Questa

    (int) temp;

    e questa

    (char) temp;

    non hanno senso.

    Basta questa al posto di tutte le righe

    str -= d;

    Ma quanto vale d? Che valore hai passato dal main?
  • Re: Linguaggio C, file e array di caratteri

    Ok, ho modificato come hai detto tu.

    L'output è:

    Ci sono 8 caratteri all'interno del file
    s[0] = a
    s[1] =
    s[2] = b
    s[3] =
    s[4] = c
    d: 1
    str[0] = `
    str[1] =
    str[2] = a
    str[3] =
    str[4] = b
    str[5] =
    str[6] = c
    str[7] =

  • Re: Linguaggio C, file e array di caratteri

    Guarda ... così si fanno mille post ma non risolvi ... quando c'è un problema (o permane il problema) mostra sempre il codice modificato compreso di main !

    Comunque, la b è cambiata in a ... quindi va bene ... gli altri caratteri non puoi vederli dato che uno spazio ha codice 32 e se ne togli 1 il codice 31 non è visibile ...
  • Re: Linguaggio C, file e array di caratteri

    Sì, scusa. Hai ragione.

    Main
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "codifica.h"
    
    int main()
    {
    	FILE *f = fopen("/home/davide/Scrivania/C/Esercitazione 6/Esercitazio 3/file.txt", "r");
    	
    	char flag, *s, *str;
    	int i = 0, d, dim;
    	
    	if(f == NULL) printf("Errore nell'apertura del file.\n");
    	else
    	{
    		//Ciclo per contare quanti caratteri 
    		//all'interno del file, in modo tale
    		//da definire la lunghezza della stringa
    		//da allocare dinamicamente
    		while(!feof(f))
    		{
    			flag = getc(f);
    			i++;
    		}
    		
    		dim = i;
    		
    		printf("\nCi sono %d caratteri all'interno del file\n", i);
    		
    		//Allocazione dinamica della stringa
    		s = (char *) malloc (i * sizeof(char));
    		
    		//Inserimento dei dati all'interno della stringa
    		i = 0;
    		
    		//Riposizionamento del cursore all'inizio del file
    		fseek(f, 0, 0);
    		
    		while(!feof(f))
    		{
    			fscanf(f, "%c", &s[i]);
    			i++;
    		}
    		
    		for( i = 0; i < dim; i++)
    			printf("s[%d] = %c\n", i, s[i]); 
    		
    		//Inserimento di d
    		printf("d: ");
    		scanf("%d", &d);
    		
    		//Invocazione della funzione codifica 
    		str = codifica(s, d);
    		
    		for(i = 0; i < dim; i++)
    			printf("str[%d] = %c\n", i, str[i]);
    		
    		fclose(f);
    	}
    	return 0;
    } 
    
    Codifica.c
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "codifica.h"
    
    char *codifica(const char* s, int d)
    {
    	int i = 0; //Indice di scorrimento per la stringa passata alla funzione
    	int dim; //Dimensione della nuova stringa
    	char temp; //Variabile di comodo per la conversione
    	char *str; //Nuova stringa
    	
    	//Serve per acquisire la dimensione
    	//della stringa per poi allocarne una
    	//nuova dinamicamente
    	while(s[i] != '\0')
    		i++;
    	
    	dim = i;
    	
    	str = (char*)malloc(i*sizeof(char));
    	
    	//Copia dei dati nella nuova stringa
    	for(i = 0; i < dim; i++)
    		str[i] = s[i];
    
    	for(i = 0; i < dim; i++)
    		str[i] -= d;
    	
    	
    	return str;
    }
    
    Comunque se dici che va bene mi fido, grazie!
Devi accedere o registrarti per scrivere nel forum
8 risposte