PDA

View Full Version : [C] LETTURA FORMATTATA DA FILE


esoni
05-05-2010, 13:06
CIAO devo fare un esercizio per la mia università,
aprire il file /etc/passwd . Si tratta di un file di testo, in cui ogni riga contiene le informazioni di un utente, e i campi all'interno di una riga sono separati da ':'. Per esempio, la riga

operator:x:37:12:Operator:/var:/bin/sh

ha il seguente significato:

* operator è il nome di login dell'utente;(stringa)
* x rappresenta il campo password (sui sistemi del Centro di Calcolo sono in uso le shadow password, per cui la password non è visibile; (stringa ,se non visibile questo campo contiene x)
* 37 è l'ID numerico dell'utente;(int)
* 12 è l'ID numerico del gruppo a cui appartiene l'utente (a volte i due valori coincidono);(int)
* Operator è il nome in chiaro dell'utente;(stringa)
* /var è l'home directory dell'utente;(stringa
* /bin/sh è la shell di login (e di default) dell'utente. (stringa)
operator:x:37:12:Operator:/var:/bin/sh


Sui sistemi UNIX, le password degli utenti sono memorizzate nel file /etc/passwd.

Si scriva un programma C che legga il file /etc/passwd, spezzando opportunamente i campi, e stampi in output i nomi in chiaro (quinto campo) di tutti gli utenti che hanno /bin/false come shell di default (ultimo campo), indicando che questi utenti non possono in nessun caso connettersi al sistema (si tratta di utenti "virtuali").

È possibile affrontare l'esercizio in (almeno) due modi:

1. leggendo le righe del file con fgets(), e usando poi dei puntatori a carattere all'interno della stringa per identificare i campi, oppure
2. usando la funzione fscanf() con le specifiche di formato %[^...] e %* (si veda il manuale: man fscanf) per spezzare automaticamente le righe al momento della lettura e assegnare solo i campi di interesse.

-------------------------------------------------------------------------------------------------------------------------------------
SONO INTERESSATO ALLA VERSIONE CON FSCANF!!!
la mia difficoltà sta inanzitutto nello spezzare i campi di ogni riga e salvare il loro contenuto.
avevo pensato una cosa del genere

while(scan!=EOF)
{
scan=fscanf(stream, "%s\t%s\t%d\t%d\t%s\%s\t%s", sutente,x,&utente,&gruppo,operator,home,shell);
}
ma la soluzione è errata quindi vorrei sapere come far andare ogni volta ogni campo nella propria variabile grazie

cionci
05-05-2010, 15:58
http://www.google.it/search?hl=it&safe=off&client=firefox-a&hs=D1K&rls=com.ubuntu%3Ait-IT%3Aunofficial&q=fscanf+using+delimiter&meta=&aq=f&aqi=&aql=&oq=&gs_rfai=

PS: nota che la soluzione ti era anche stata suggerita nel testo: con le specifiche di formato %[^...] e %*

esoni
05-05-2010, 20:11
se mi puoi chiarire con un esempio te ne sarei grato ;-)

esoni
05-05-2010, 23:48
seguendo l esempio ho fatto questa mia versione provando intanto se andava x la prima riga...ma stampa caratteri strani
FILE *stream;
char sutente[20];
char x[20];
int utente;
int gruppo;
char operator[20];
char home[20];
char shell[20];
int scan=0;
stream = fopen("/etc/passwd", "r");


if ((stream = fopen("/etc/passwd", "r")) == NULL)
{
printf("Non posso aprire il file %s", "/etc/passwd.txt");
exit(1);
}else

scan=fscanf(stream, "[^':'],[^':'],[^':'],[^':'],[^':'],[^':'],[^':']", sutente,x,&utente,&gruppo,operator,home,shell);
printf("%s %s %d %d %s %s %s", sutente, x,utente,gruppo,operator,home,shell);

che sbaglio?

esoni
06-05-2010, 00:42
SCUSATE AVEVO SBAGLIATO IL CODICE... HO AGGIUSTATO MA NON FUNZIONA =
#include <stdlib.h>
#include <malloc.h>
#include <ctype.h>
#include<string.h>
#include<stdio.h>
int main(){
FILE *stream;
char buf[200];
char sutente[20];
char x[20];
char ut[20];

int utente;
char gr[20];
int gruppo;
char operator[20];
char home[20];
char shell[20];
int scan;

stream = fopen("/etc/passwd", "r");
scan=fscanf(stream, "%[^':'],%[^':'],%[^':'],%[^':'],%[^':'],%[^':'],%s",sutente, x, ut,gr,operator,home,shell);
utente=atoi(ut);
gruppo=atoi(gr);
printf (" %s %s %s %s %s %s %s",sutente,x,ut,gr,operator,home,shell);



MI DOVREBBE STAMPARE LA 1 RIGA DEL FILE PSWD,USANDO IL CONTENUTO DELLE VARIABILI MA STAMPA COSE STRANE

cionci
06-05-2010, 09:03
Che ci fa la virgola ? Il tuo delimitatore non è la virgola. Comunque di esempi ne trovavo se andavi a vedere nella ricerca che ti avevo linkato.

esoni
06-05-2010, 09:35
hai ragione ! risolto ,sostituito i : con la virgola...
un ultima cosa per fare il ciclo X LEGGERE ogni riga fino a fine file, come faccio ?



scan=fscanf(stream, "%[^':'],%[^':'],%[^':'],%[^':'],%[^':'],%[^':'],%s",sutente, x, ut,gr,operator,home,shell);

while(scan!=EOF)
{
scan=fscanf(stream, "%[^':']:%[^':']:%[^':']:%[^':']:%[^':']:%[^':']:%s",sutente, x, ut,gr,operator,home,shell);
//STAMPO ARG CHE MI INTERESSANO
}


INVECE MI STAMPA VALORI ALL INFINITO....STRANO XCHE HO TROVATO UN PROGRAMMA SIMILI E AVEVA LA MEDESIMA SOLUZIONE...CHE SBAGLIo?

cionci
06-05-2010, 09:49
c'è una funzione che si chiama feof()
Quella situazione l'hai trovata quando si va a leggere un carattere alla volta e non è questo il caso.

esoni
06-05-2010, 10:33
ho aggiustato con la feof() come mi hai dettio te ma continua a stampare in loop infiniti valori...
------
mio codice:VORREI STAMPARE DI OGNI RIGA DI PASSWD IL 5° E IL 7° CAMPO


int main(){
FILE *stream;
int result;
char t[20];
char u[20];
stream=fopen("/etc/passwd","r");
if ((stream = fopen("/etc/passwd", "r")) == NULL)
{
printf("Non posso aprire il file %s", "fo");
exit(1);
}


result = fscanf(stream,"%*[^':']:%*[^':']:%*[^':']:%*[^':']:%[^':']:%*[^':']:%s",t,u);
while(!feof(stream)) {

printf("%s %s",t,u);
result = fscanf(stream,"%*[^':']:%*[^':']:%*[^':']:%*[^':']:%[^':']:%*[^':']:%s",t,u);
}
fclose(stream);
}


HELP STO IMPAZZENDO