Sscanf
Ciao a todos!
Io dovrei leggere da file una stringa mista di numeri e caratteri. Solo che chiaramente i numeri mi servono non in formato carattere, ma come valori. Che comando devo usare? Sscanf? Non ho ben capito il suo funzionamento. Oppure devo scannerizzare come stringa di caratteri e poi convertire in qualche modo i numeri? Qualcuno magari può farmi un esempio?
Grazie!
Paola
Io dovrei leggere da file una stringa mista di numeri e caratteri. Solo che chiaramente i numeri mi servono non in formato carattere, ma come valori. Che comando devo usare? Sscanf? Non ho ben capito il suo funzionamento. Oppure devo scannerizzare come stringa di caratteri e poi convertire in qualche modo i numeri? Qualcuno magari può farmi un esempio?
Grazie!
Paola
Risposte
Per darti il miglior consiglio ho bisogno di alcune informazioni:
Il file e' un insieme di record ?
Il file viene gestito interamente dal tuo programma (che vuoi realizzare) ?
E' un file preso a caso da un'altra fonte che conosci la posizione e il formato dei dati da estrarre ?
Il file e' un insieme di record ?
Il file viene gestito interamente dal tuo programma (che vuoi realizzare) ?
E' un file preso a caso da un'altra fonte che conosci la posizione e il formato dei dati da estrarre ?
Non so cosa sia un insieme di record..!
Cmq il file è gestito così: lo crea l'utente secondo certi parametri (è su più righe e ogni riga ha una determinato numero di caratteri. Il programma chiede il nome del file all'utente e poi legge una riga a caso (anche per questo effettivamete avrei bisogno di un consiglio? Come gli dico di leggere la riga n-esima invece di partire dalla 1°?).
Ti servono altre info?
Paola
Cmq il file è gestito così: lo crea l'utente secondo certi parametri (è su più righe e ogni riga ha una determinato numero di caratteri. Il programma chiede il nome del file all'utente e poi legge una riga a caso (anche per questo effettivamete avrei bisogno di un consiglio? Come gli dico di leggere la riga n-esima invece di partire dalla 1°?).
Ti servono altre info?

Paola
Vediamo se ho capito.
Il file e' strutturato da un'insieme di righe in cui ogni riga e' formata da un'insieme di valori. Questo insieme di valori a livello testo e' visto come una stringa ovviamente).
Osservazione:
La stringa puo' contenere spazi se un valore e' pari a 32 (codice ascii dello spazio)
In questo caso sconsiglio la lettura a stringhe.
Domande:
1) I valori da leggere da quanti bit sono formati ?
Esempio:
(4 bit = ogni carattere costituisce 2 valori)
(8 bit = ogni carattere costituisce 1 valori)
(16 bit = ogni 2 caratteri costituiscono un 1 valore)
2) Ogni riga contiene sempre lo stesso numeri di valori ?
In questo caso utilizzeremo i record.
Il file e' strutturato da un'insieme di righe in cui ogni riga e' formata da un'insieme di valori. Questo insieme di valori a livello testo e' visto come una stringa ovviamente).
Osservazione:
La stringa puo' contenere spazi se un valore e' pari a 32 (codice ascii dello spazio)
In questo caso sconsiglio la lettura a stringhe.
Domande:
1) I valori da leggere da quanti bit sono formati ?
Esempio:
(4 bit = ogni carattere costituisce 2 valori)
(8 bit = ogni carattere costituisce 1 valori)
(16 bit = ogni 2 caratteri costituiscono un 1 valore)
2) Ogni riga contiene sempre lo stesso numeri di valori ?
In questo caso utilizzeremo i record.
Ti faccio un esempio di riga
5--3--7-3-2-----9-4--9-3-1--
Ogni riga deve rappresentare uno schema di Sudoku.
i trattini "-" mi servono, perchè indicano uno spazio vuoto nello schema. Conta poi che tutti i numeri sono formati da una cifra sola essendo Sudoku. Ecco, il mio problema è: come faccio a leggere una riga "mista"?
Ogni riga, contiene 81 elementi. Il file che devo leggere contiene vari schemi e il mio programma poi ne sceglie uno a caso.
Paola
5--3--7-3-2-----9-4--9-3-1--
Ogni riga deve rappresentare uno schema di Sudoku.
i trattini "-" mi servono, perchè indicano uno spazio vuoto nello schema. Conta poi che tutti i numeri sono formati da una cifra sola essendo Sudoku. Ecco, il mio problema è: come faccio a leggere una riga "mista"?
Ogni riga, contiene 81 elementi. Il file che devo leggere contiene vari schemi e il mio programma poi ne sceglie uno a caso.
Paola
Ultime due domande e poi all'opera.
1) Vuoi rappresentare la griglia a video ?
2) Tra un sudoku e l'altro c'e' solo un invio ?
Cioe' e' scritto puro come segue:
--1--9--5-----4......
3--7---76----2.....
e non per esempio
Sudoku n.1 Griglia: ---4----7---5
1) Vuoi rappresentare la griglia a video ?
2) Tra un sudoku e l'altro c'e' solo un invio ?
Cioe' e' scritto puro come segue:
--1--9--5-----4......
3--7---76----2.....
e non per esempio
Sudoku n.1 Griglia: ---4----7---5
Sì dopo la dovrò rappresentare in una finestra grafica.
Secondo te mi conviene considerarli come caratteri i numeri? Perchè dopo dovrò impostare un metodo risolutivo...
Per quanto riguarda le righe di file, sì sono "pure" TRa ogni schema c'è solo un invio, come nel primo esempio che hai fatto!!
Paola
Secondo te mi conviene considerarli come caratteri i numeri? Perchè dopo dovrò impostare un metodo risolutivo...
Per quanto riguarda le righe di file, sì sono "pure" TRa ogni schema c'è solo un invio, come nel primo esempio che hai fatto!!

Paola
Perfetto!
utilizzero' un metodo standard C e tutto quello che scrivero' di seguito e' sempre da verificare.
Abbiamo bisogno di sapere quanti sudoku contiene il file.
(In questo caso ogni sudoku corrisponde ad un record).
Ogni riga contiene un record + un invio, siccome ogni record e' composto da 81 caratteri, ogni riga ha la dimensione di 82 caratteri, ossia 82 bytes.
La dimensione del file in bytes diviso 82 ci restituisce il numero dei record.
Dichiarazione varibili e costanti:
ricaviamo il numero dei record:
generiamo il numero casuale del sudoku da leggere:
peschiamo il sudoku dal file:
convertiamo i caratteri in numeri:
credo che hai tutto per proseguire.
Se ti occorre un ulteriore aiuto anche su come rappresentare un sudoku oppure qualche chiarimento chiedi pure.
A presto,
Eugenio
utilizzero' un metodo standard C e tutto quello che scrivero' di seguito e' sempre da verificare.
Abbiamo bisogno di sapere quanti sudoku contiene il file.
(In questo caso ogni sudoku corrisponde ad un record).
Ogni riga contiene un record + un invio, siccome ogni record e' composto da 81 caratteri, ogni riga ha la dimensione di 82 caratteri, ossia 82 bytes.
La dimensione del file in bytes diviso 82 ci restituisce il numero dei record.
Dichiarazione varibili e costanti:
/* costanti */ #define nCol 9 // numero di colonne di un sudoku #define nRow 9 // numero di righe di un sudoku #define rowSize 82 // dimensione di una riga /* struttura del sudoku */ /* matrice 9*9 */ typedef struct { char value[nCol][nRow]; } sudokuType; /* variabili */ sudokuType sudoku; // variabile sudoku; int sudokuValue[nCol][nRow]; valori numerici del sudoku che dovrai utilizzare successivamente FILE *fp; // puntatore al file long fileSize; // dimensione del file long numRec; // numero dei record ovvero dei sudoku long index; // indice del sudoku da leggere
ricaviamo il numero dei record:
fp = fopen.... // esegui sempre il controllo dell'esistenza del file fseek(fp, 0, SEEK_END); // si punta alla fine del file fileSize = ftell(fp) + 1; // Un file e' grande quanto la sua posizione finale + 1 numRec = fileSize / rowSize; fclose (fp);
generiamo il numero casuale del sudoku da leggere:
// ...non dimenticare il randomize nel main .... index = rand() % numRec // restituisce un valore da 0 a numRec - 1
peschiamo il sudoku dal file:
fp = fopen.... // come prima esegui sempre il controllo dell'esistenza del file fseek(fp, index * rowSize, SEEK_SET); // puntera' all'inizio del sudoku che vogliamo leggere fread(fp, sizeof(sudokyType), 1, sudoku); fclose(fp);
convertiamo i caratteri in numeri:
// scansione valore per valore for(c = 0; c < nCol; c++) for(r = 0; r < nRow; r++) if(sudoku.value[c][r] == '-') sudokuValue[c][r] = 0; else sudokuValue[c][r] = sudoku.value[c][r] - 48;
credo che hai tutto per proseguire.
Se ti occorre un ulteriore aiuto anche su come rappresentare un sudoku oppure qualche chiarimento chiedi pure.
A presto,
Eugenio
Ok me lo sono letto attentamente e mi pare chiaro tutto. Una cosa: perchè proprio nell'ultima riga sottrai 48?
Grazie!!
Paola
Grazie!!
Paola
Per convertire il carattere in numero.
Se tieni premuto ALT mentre scrivi 48 sul tastierino numerico e poi lo lasci e come se avessi premuto 0.
Perche' il codice ascii di 0 e' 48.
'0' = ascii 48 ossia 48 + 0
'1' = ascii 49 ossia 48 + 1
...
'9' = ascii 57 ossia 48 + 9
per esempio se sudoku.value[c][r] = '3'
e come se sudoku.value[c][r] = 51 quindi sudoku.value[c][r] - 48 = 3.
In sostanza 'x' = 48 + x quindi x = 'x' - 48 dove x va da 0 a 9.
ok ?
Se tieni premuto ALT mentre scrivi 48 sul tastierino numerico e poi lo lasci e come se avessi premuto 0.
Perche' il codice ascii di 0 e' 48.
'0' = ascii 48 ossia 48 + 0
'1' = ascii 49 ossia 48 + 1
...
'9' = ascii 57 ossia 48 + 9
per esempio se sudoku.value[c][r] = '3'
e come se sudoku.value[c][r] = 51 quindi sudoku.value[c][r] - 48 = 3.
In sostanza 'x' = 48 + x quindi x = 'x' - 48 dove x va da 0 a 9.
ok ?
Ok tutto chiaro! Non sapevo questa cosa dell'ASCII!!
Se sorgono altri problemi scrivo sul forum, ma spero di doverti disturbare il meno possibile!!
Grazie ancora, sei la mia salvezza!!
Paola
Se sorgono altri problemi scrivo sul forum, ma spero di doverti disturbare il meno possibile!!

Grazie ancora, sei la mia salvezza!!
Paola
Disturba pure senza problemi.
E' un piacere per me.
A presto,
Eugenio
P.S.
Come hai potuto notare la conoscenza dei codici ascii aiuta a gestire i caratteri numericamente.
Su internet puoi trovare molto facilemnte una tabella di tutti i codici ascii.
Esempio di comodita':
immaginiamo una variabile (ch) di tipo carattere, che legge un carattere casuale dal file.
Per sapere se questa variabile contiene una lettera minuscola basta fare uno dei seguenti confronti:
codice ascii di 'a' = 97
codice ascii di 'z' = 122
if(ch >= 97 && ch <= 122)
{ ...e' una lettera minuscola...}
oppure piu' semplicemente
if(ch >= 'a' && ch <= 'z')
{ ...e' una lettera minuscola...}
se scrivo 'a' e 'z' al posto 97 e 122 non cambia nulla.
se vuoi verificare invece che si tratti di un numero scrivi:
if(ch >= 48 && ch <= 57)
{ ...e' un numero...}
oppure piu' semplicemente
if(ch >= '0' && ch <= '9')
{ ...e' un numero...}
E' un piacere per me.
A presto,
Eugenio
P.S.
Come hai potuto notare la conoscenza dei codici ascii aiuta a gestire i caratteri numericamente.
Su internet puoi trovare molto facilemnte una tabella di tutti i codici ascii.
Esempio di comodita':
immaginiamo una variabile (ch) di tipo carattere, che legge un carattere casuale dal file.
Per sapere se questa variabile contiene una lettera minuscola basta fare uno dei seguenti confronti:
codice ascii di 'a' = 97
codice ascii di 'z' = 122
if(ch >= 97 && ch <= 122)
{ ...e' una lettera minuscola...}
oppure piu' semplicemente
if(ch >= 'a' && ch <= 'z')
{ ...e' una lettera minuscola...}
se scrivo 'a' e 'z' al posto 97 e 122 non cambia nulla.
se vuoi verificare invece che si tratti di un numero scrivi:
if(ch >= 48 && ch <= 57)
{ ...e' un numero...}
oppure piu' semplicemente
if(ch >= '0' && ch <= '9')
{ ...e' un numero...}
"eugenio.amitrano":
sudokuValue[c][r] = sudoku.value[c][r] - 48;
sudokuValue[c][r] = sudoku.value[c][r] - '0';
Più portabile.

Bravo!
Funziona anche scrivendo '0' al posto di 48.
Eugenio
Funziona anche scrivendo '0' al posto di 48.
Eugenio
// scansione valore per valore for(c = 0; c < nCol; c++) for(r = 0; r < nRow; r++) if(sudoku.value[c][r] == '-') sudokuValue[c][r] = 0; else sudokuValue[c][r] = sudoku.value[c][r] - 48;
lo farei diventare
// scansione valore per valore for(c = 0; c < nCol; c++) for(r = 0; r < nRow; r++) sudokuValue[c][r] = (sudoku.value[c][r] == '-') ? 0 : atoi(sudoku.value[c][r]);
int atoi ( const char * string ), si trova nella stdlib.h e converte una stringa in un intero... perchè non usarla?

per il resto il codice di eugenio.amitrano mi sembra molto buono

Ciao groucho, (questo personaggio mi e' molto simpatico)
benvenuto nel forum e complimenti per la preparazione informatica. Sono sicuro che la tua presenza dara' grande valore aggiunto al forum.
Volevo segnarti un'imprecisione:
atoi(sudoku.value[c][r]);
non funziona, perche' come hai scritto tu, vuole come parametro una stringa e non un carattere.
Per farla funzionare si potrebbe effettuare un trasferimento in una stringa di un carattere piu' il NIL.
A presto,
Eugenio
benvenuto nel forum e complimenti per la preparazione informatica. Sono sicuro che la tua presenza dara' grande valore aggiunto al forum.
Volevo segnarti un'imprecisione:
atoi(sudoku.value[c][r]);
non funziona, perche' come hai scritto tu, vuole come parametro una stringa e non un carattere.
Per farla funzionare si potrebbe effettuare un trasferimento in una stringa di un carattere piu' il NIL.
A presto,
Eugenio
vedi la fretta a volte?
ahah... non ci avevo nemmeno pensato al fatto che fosse un carattere...

ahah... non ci avevo nemmeno pensato al fatto che fosse un carattere...
