Newsgroup: it.comp.lang.c
Titolo: fscanf()

Ciao a tutti,
ho un file di testo contenente una serie di dati relativi agli utenti di
un'applicazione che dovrà girare su terminali portatili, il file è così
strutturato:
IDUtente,Username,Nome Reale
ad esempio:
1,pippo,Filippo Ughini
2,pappo,Elide Mizzeca
3,poppo,Zuzzu Rellone
Ho provato ad utilizzare la funzione fscanf() per splittare la stringa in
più variabili ma se utilizzo 3 argomenti come parametri si blocca il
programma.
----------
unsigned int usrid; /* user ID */
char usrnm[10];    /* username */
char realnm[30]; /* nome reale */
...CUT
/* "in" è un tipo FILE */
fscanf(in, "%d,%s,%s", &bufid, bufnm, realnm);
----------
Qualcuno può HELParmi? ;) In VisualBasic6 c'era la comodissima funzione
Split!
saluti

 Split!
In realtà il problema è un po' complesso, (penso anche in Visual Basic).
La particolarità di questo problema è il seguente:
Come fa lo scansore a capire quando finisce il username e comincia il campo
nome. Come fa a capire quando finisce il campo nome?
Hai bisogno di usare dei delimitatori di campo (impliciti tipo lunghezza o
espliciti tipo delimitatori). In questo caso tu ce li hai: le virgole.
Allora devi fare un ciclo di acquisizione carattere per carattere per
ciascuno dei campi testuali:
/*Dichiarazione di un intero c che mi servirà per acquisire i caratteri da
file*/
int c;
/*Lettura dell'ID*/
fscanf(in,"%d,",&bufid);
/*Lettura dello username*/
i=0;
while((c=fgetc(in))!=EOF && c!=',' )
    bufnm[i++]=(char)c;
bufnm[i]='\0';
/*Lettura del nome*/
i=0;
while((c=fgetc(in))!=EOF && c!='\n' )
    realnm[i++]=(char)c;
realnm[i]='\0';
P.S. Con questa tecnica sei sicuro di aver scritto un algoritmo assai
robusto (non troppo perchè ho omesso tutti i controlli di errore sui file):
Se un nome di persona è composto da tre parti (De Filippo Peppino) come
faresti? fscanf("%d,%s,%s %s %s");
Ricordati che %s si ferma alla prima occorrenza di uno spazio (e non solo).
Se sono stato troppo ermetico è perchè l'accesso remoto casalingo costa
ancora un po' troppo! Se hai ancora dubbi, non esitare a rispondermi.
Ciao,
johnpp

Ciao John,
grazie 1000 per la pronta ed efficiente risposta!
Non sapevo che in C si dovevano fare tanti ghirigori per una roba simile, va
beh che comunque stiamo parlando di un linguaggio a basso livello, quindi è
comprensibile che non esistano funzioni belle pronte! ;)
Avevo considerato la possibilità di acquisire carattere per carattere, ma
pensavo ci fossero altre soluzioni. Se cosi non è, partendo dal Tuo esempio,
vedrò di costruire un'apposita funzione simile a Split() di VB.
Ti ringrazio ancora e alla prox!
zerodefex


 ghirigori per una roba simile
In effetti si puň fare in maniera piů semplice:
    fscanf(in, "%d,%[^,],%[^\n]", &bufid, bufnm, realnm);
In questo modo la ricerca di bufnm viene interrotta quando viene trovata la
virgola, mentre la ricerca di realnm alla fine della riga.
Maurizio.

WOW, grazie anche a te!!!!


     fscanf(in, "%d,%[^,],%[^\n]", &bufid, bufnm, realnm);
Questa non la sapevo! Grande! Sul Kernigham avevo letto che il formattatore
%[???] serviva per leggere stringhe i cui caratteri erano segnati li dove ho
messo i punti interrogativi. Ma quella della negazione č grande. Ma č
standard?
johnpp

 Ma č standard?
Credo proprio di sě. In ogni caso se ne era parlato recentemente in questo
ng.
Maurizio.