Newsgroup: it.comp.os.linux.development
Titolo: Trovare il numero di caratteri dal nome di un file

Ciao a tutti, devo scrivere una versione personalizzata del comando ls
sotto linux ma mi sono bloccato in un punto: in pratica devo risalire
al numero di caratteri che conpongono il nome del file all'interno di
una directory per trovare il più lungo in maniera da decidere quante
colonne fare per la stampa a video. Per fare questo mi appoggio sulla
libreria dirent.h che ha questa struttura:
struct dirent {
	long                  d_ino;
	__kernel_off_t   d_off;
	unsigned short  d_reclen;
	char		      d_name[256]; /* We must not include limits.h! */
};
e ho bisogno proprio del campo d_name che mi restituisce il nome del
file, dopodichè usando strlen risalgo al numero dei caratteri, molto
facile a parole ma all'atto pratico mi ritrovo un segmentatio fault che
non riesco a capire da dove salti fuori..
Il mio codice è semplice:
void do_ls(char dirname[])
{
    DIR            *dir_ptr;   /* la directory   */
    struct dirent  *direntp;   /* ciascuna entry */
    if( (dir_ptr = opendir(dirname)) == NULL )
	fprintf(stderr,"ls1: cannot open %s\n",dirname);
    else
    {
	while( (direntp = readdir(dir_ptr)) != NULL )
	printf("%s\n",direntp->d_name);
	closedir(dir_ptr);
    }
}
Ed è funzionante al 100%! direntp->d_name pesca il nome di ogni file
che viene scansionato, per trovare il numero di caratteri pensavo di
utilizzare queste due righe di codice prese da manuale:
size_t len; //per inizializzare la variabile
len = strlen(direntp->d_name); //per trovare il numero dei caratteri
ma mi da segmentation fault.. Come fareste voi al mio posto?
Grazie, ciao.

 ma mi da segmentation fault.. Come fareste voi al mio posto?
Io posterei il codice che non funziona. Ma prima eseguirei il processo
all'interno di gdb per vedere dove avviene il segfault.
Luca
-- 
Home: 
http://kronoz.cjb.net
Ci sono due cose che l'uomo non puo` nascondere:
essere ubriaco ed essere innamorato.

 .. Come fareste voi al mio posto?
#!/usr/bin/python
import os
max([len(filename) for filename in os.listdir('nomedirectory')])
-- 
Taekyon

 all'interno di gdb per vedere dove avviene il segfault.
il gdb mi diche che è nella strlen il segfault

Taekyon ha scritto:

questa mi e' piaciuta! :-)
-- 
Felinux, The Italian Way: 
http://www.fmtec.it/felinux

 ha scritto:

No e' del tutto esatto, guarda meglio. Dal codice che hai postato su
iclc:
Program received signal SIGSEGV, Segmentation fault.
0xa7ee675b in strlen () from /lib/tls/libc.so.6
(gdb) bt
#0  0xa7ee675b in strlen () from /lib/tls/libc.so.6
#1  0xa7ed22f5 in puts () from /lib/tls/libc.so.6
#2  0x08048511 in do_ls (dirname=0x8048674 ".") at tmp.c:17
#3  0x0804853f in main () at tmp.c:23
(gdb) frame 2
#2  0x08048511 in do_ls (dirname=0x8048674 ".") at tmp.c:17
17                      printf("%s\n",direntp->d_name);
(gdb) quit
Come ti e' stato giustamento detto di la, manca un paio di parentesi nel
ciclo while.
Luca
-- 
Windows NT: Designed for the Internet. The Internet: Designed for Unix.

 Windows NT: Designed for the Internet. The Internet: Designed for Unix.
E' vero, alla fine era solo un problema di parentesi.. uno stupido
errore di distrazione.. :-(
Grazie a tutti per le risposte!

 questa mi e' piaciuta! :-)
In Tcl viene un po' piu` lungo, ma fa i calcoli giusti per il numero di
*caratteri* (che non sono sempre byte...), cosa che la versione in C non
fa, e neanche necessariamente la versione in Python, se non erro.
set l 0 ; foreach f [glob *] {
    set fl [string length $f] ;
    set l [expr {$fl > $l ? $fl : $l}]
}
puts "longest filename is $l"
-- 
David N. Welton
- 
http://www.dedasys.com/davidw/
Linux, Open Source Consulting
- 
http://www.dedasys.com/

 fa, e neanche necessariamente la versione in Python, se non erro.
python lavora tramquillamente in unicode, se intendi questo, ma comunque
len(unicode(stringa)) dovrebbe togliere ogni dubbio :D
-- 
Under construction

 fa, e neanche necessariamente la versione in Python, se non erro.
Uhm no, la riga che ho scritto restituisce il numero di caratteri, non di
byte.
-- 
Taekyon


Sono confuso allora.  So che Python ha sia stringhe unicode che stringhe
'C-style'.  Quando usa l'una e l'altra?


 'C-style'.  Quando usa l'una e l'altra?
Uhm ... non sono un guru, appena appena mastico un poco di python.
Le stringhe unicode si dichiarano appositamente mettendo una u all'inizio.
Per quanto ne so la funzione len() si può applicare ad una serie di
oggetti - stringe normali, stringhe unicode, liste, tuple ecc. e
restituisce un numero intero pari al numero di componenti dell'oggetto.
Quindi, sia che si tratti di una comune stringa 'abcd' (che non è come la
stringa C, la stringa python è un oggetto immutabile) sia che sia una
stringa unicode come u'Hello\u0020World !' len() restituisce il numero di
caratteri: len('abcd') = 4, len(u'Hello\u0020World !') = 13 perché \u0020 è
l'escape unicode per un unico carattere - lo spazio). Se ho ben capito la
tua domanda - ma confesso la mia ignoranza in materia - tu dici che un
certo carattere unicode (ad esempio per un ideogramma vietnamita) potrebbe
essere di un numero di byte più alto che non un comune carattere ascii. A
quanto ho capito io però la funzione len() lo conterebbe sempre comunque
come un unico carattere.
-- 
Taekyon

>> len(os.listdir('.')[0])
3
# il nome comprende tre caratteri
-- 
Taekyon

>> len(os.listdir('.')[0])
6
Errato!  Sono solo 2 caratteri, e sei byte!
In termini di ambiente, ho questo:
declare -x LANG="en_US.UTF-8"


>>  
-- 
Under construction

 (u'\u2200\u2200', <type 'unicode'>)
OK, se ho ben capito mi confermi che il numero di byte non c'entra per nulla
con la funzione len() - in questo caso misura 6 oppure 2 caratteri in base
alla codifica che gli dici di usare, non misura comunque il numero di byte?
-- 
Taekyon

 di byte?
Ni :D
len(), applicato ad una stringa, ritorna il numero di caratteri della
stringa.
se la stringa a cui e' applicato len() e' in "ascii"ą (cioe'
type(stringa)=='str') allora vale l'assunto "un carattere == un byte"
se la stringa a cui e' applicato len() e' un oggetto unicode
(type(stringa)=='unicode') l'assunto NON vale 
ąLa cosa in effetti "dovrebbe" dipendere dalla codifica, ma in genere vale
per tutte quelle "non unicode", tipo iso-8859-XX
-- 
Under construction