Newsgroup: it.comp.lang.c
Titolo: rinominare file

Ciao a tutti, in windows xp ho una cartella con circa 400 video che vorrei 
rinominare in ordine numerico.
I nomi dei file contengono il numero del video pero non sono tutti 
strutturati uguali per esempio:
video 1.avi, video 2.avi, video mario 3.avi,  4 video.avi, ecc
io vorrei ottenere come nome file di ogni video questo:
1 video 1.avi
2 video 2.avi
3 video mario 3.avi
4 video.avi (perche il 4 è gia il primo carattere).
è possibile realizzarlo in c? Io ho programmato quasi sempre con la libreria 
standard a scopo didattico, ho provato per curiosita a usare le gtk ma solo 
per la grafica.
Cosa mi consigliate? non ditemi di rinominarli a mano che sono piu di 400 
:-)
Grazie mille 

 è possibile realizzarlo in c?
Certo;non ho capito proprio esattamente cosa vuoi
fare ma ho fatto cose peggiori prima di scoprire un
programma free che fa di tutto di più - ma
sicuramente non quello che ti serve.
In casi del genere faccio un batch che fa scrivere
la directory su un file di testo che viene aperto
dal programma, letto linea per linea e a seconda dei
casi genera un batch con le istruzioni o si chiama
il comando con "system ()". Ci saranno modi più
adatti al sistema operativo ma si sa, i poveri
utenti di win XP... :/
Il processamento della linea dipenderà da che devi
fare. Se ci sono sempre spazi puoi dichiarare un
numero elevato di stringhe e leggerle tutte con
"sscanf" che ti ritornerà il numero di sottostringhe
lette, poi ci fai quel che ti serve. Se no ti serve
un parser ma mi sa che è come ammazzare le formiche
con uno schiacciasassi.
-- 
Computer multitasking: oggetto che
può essere messo fuori uso da più
persone contemporaneamente.


Non ho capito come passi da stringa a numero. Basta prendere un numero
dentro al nome? E se ci sono più numeri? e se di numeri non ce ne
sono? etc.etc.
Direi che iniziare a stabilire delle regole di trasformazione sia la
base per scrivere un algoritmo che le segua.
Ciao!

-Non ho capito come passi da stringa a numero. Basta
-prendere un numero
-dentro al nome?
si, il file video 1.avi deve diventare 1 video1.avi perche č il video 1 
quindi il primo.
-E se ci sono piů numeri?
no, solo un numero per ogni nome del file.
-e se di numeri non ce ne
-sono?
č sempre presente un solo numero ma non si sa dove, potrebbe essere all 
inizio, a meta, o alla fine della stringa.
-Direi che iniziare a stabilire delle regole di trasformazione -sia la
-base per scrivere un algoritmo che le segua.
Chiedevo appunto per sapere se qualcuno sa risolverlo in maniera veloce... 
anche perche i casi possibili sono davvero molti, e le stringhe da gestire 
non sono semplici.
fatemi sapere
grazie mille 

Magari esistesse un free per quello... comunque gestire il file di testo 
risultante dalla tua procedura è molto complicato, non so quanto conviene...
Se ti viene in mente altro fammi sapere.
Ciao ciao 


non so, se sei sotto Linux credo che le chiamate per
la gestione di files e directories dovrebbero essere
pressoché native... io sono sotto XP, e più semplice
di come ti ho detto non saprei; bisogna fare solo un
batch con "dir *.avi > elenco.txt <CR> mioprog.exe",
aprire il file dal programma e leggerlo linea per
linea... se è complicato questo allora non so
davvero che dire :(


non so, se sei sotto Linux credo che le chiamate per
la gestione di files e directories dovrebbero essere
pressoché native... io sono sotto XP, e più semplice
di come ti ho detto non saprei; bisogna fare solo un
batch con "dir *.avi > elenco.txt <CR> mioprog.exe",
aprire il file dal programma e leggerlo linea per
linea... se è complicato questo allora non so
davvero che dire :(
è proprio il leggerlo linea per linea che è complicato, le stringhe non 
hanno struttura fissa e con la libreria tandard diventa complicato.
Magari sono io che non arrivo a capire come farlo...
ps: il problema sta su XP, potrei trasferire tutto su linux ma preferirei 
programmare in XP perche sotto linux non ho esperienza.
Grazie ancora
ciaoo 

 ciaoo
se proprio devi farlo in C senza gli strumenti unix-like, e vuoi
mantenere una certa flessibilità e "cortezza" del codice, usa una
libreria di regex (regular expressions).
Risolvi tutto con una stringa tipo: "^.*([0-9]*).*$"
altrimenti una funzione che tira fuori un numero non sembra difficile
(senza controllo di errore e con le regole che mi hai detto prima)
long find_number(char *str)
{
    while(*str<'0' || *str>'9') ++str;
    return strtol(str, NULL, 10);
}
mentre le righe dal file (o dallo stdin, come ti hanno suggerito) le
leggi con qualcosa tipo (senza controlli di errore, come prima):
char buf[80];
long l;
while(fgets(buf, 80, fileptr)) {
    l = find_number(buf);
    /* qualcosa con l */
}
Ciao!

 esperienza. Grazie ancora ciaoo
invece c'è la soluzione quick and diry. Una cosa
tipo questa:
/* INIZIO SEZIONE */
char    substrings[10][20] ;
char    buf [81] ;
int       nsubs ;
int       numero_file ;
/* qui leggi la linea del file, starà dentro un loop */
fgets (buf,80,f_input) ;
/* può leggere al massimo tre sottostringhe ma si
generalizza banalmente */
nsubs = sscanf (buf,
                           "%s %s %s",
                           substrings[0],
                           substrings[1],
                           substrings[2]) ;
/* ora 'nsubs' contiene il numero di sottostringhe
effettivamente lette, poi ci fai quel che ti serve */
/* FINE SEZIONE */
Dopodiché, se sai che nell'ultima stringa ci sarà
sempre un numero farai qualcosa tipo
sscanf(substrings[nsubs-1],"%d",&numero_file) ;
e così via.
Non ditemi che è un orrore che lo so da me; ma
almeno si può fare mentre con una mano si controlla
un videogame e in cuffia ci sta musica a palla.
Dovessi farne un'applicativo commerciale ovviamente
mi saprei regolare di conseguenza :D
Infine, non può proprio essere che la stringa non
abbia davvero un minimo straccio di pattern, perché
se no non avresti il problema di rinominare in base
al nome.


Scusate se non quoto, ho dei problemi nel programma che sto usando.
Appena ho tempo studio sia il tuo metodo che quello di ftm e provo a buttare 
giu qualcosa.
le stringhe sono quasi tutte diverse tra loro come struttura, nel senso che 
sono formate da parole di lunghezza diversa e a volte possono comparire 
anche caratteri come parentesi quadre punteggiatura ecc...L'unica cosa certa 
è che hanno tutte un numero, e io devo rinominarle e ordinarle in base a 
quel numero.
Se riesco a fare l'algoritmo per trovare il numero di ogni puntata e 
inserirlo all' inizio della stringa poi come faccio a rinominare i file 
nella directory? Dopo che ho in memoria tutte le stringhe rinominate come 
faccio a leggere i nomi dei file per poter sovrascrivere il nome?
Grazie ancora, siete stati gentilissimi.
Ciaoo

 gentilissimi.
Eh, un corso di "c" è fuori dalle mie possibilità ma
in sostanza puoi fare qualcosa del tipo (studiati i
comandi DOS, che ti conviene):
char buf[81] ;
sprintf(buf,"ren %s %s","vecchiofile","nuovofile") ;
system (buf) ;
eccetera...



Se le regole sono esattamente come quelle che ha descritto l'OP, la
funzione che ho postato io prima basta e avanza (ovvero riconosce il
pattern ".*([0-9]*).*").
Ciao!

comandi DOS, che ti conviene):
Avevo letto che anche nelle librerie std vi sono funzioni che rinominano 
cancellano e agiscono sui file del SO.
non si potrebbero usare nel mio caso?
Tipo che io trovo il numero nel nomefile, salvo su un buff il nuovo titolo e 
poi uso una la funzione delle std per rinominare il file con buff. Potrebbe 
andare?
Se la funzione di atm per trovare il numero funziona, potrebbe essere una 
risoluzione semplice del problema...
GRazie ancora
ciao ciao

la funzione che ho postato io prima basta e avanza (ovvero riconosce il
pattern ".*([0-9]*).*").
Ciao!
Pero non mi è chiara... provo a spiegare cosa ho capito:
Leggo i nomi dei file con un loop e salvo su buff, ad ogni lettura richiamo 
find_number che trova il numero ovunque sia leggendo i singoli caratteri 
fino a quando trova un 'carattere numero', a questo punto pero converte in 
intero da quel carattere fino alla fine del nomefile, quindi dovrei contare 
prima quanti caratteri ha il num e poi convertirlo... Giusto?
Grazie ancora
ciao 


while(*str<'0' || *str>'9') ++str;
/* scorre finché non trova un carattere tra 0 e 9 compresi */
strtol(str, NULL, 10);
/* converte str in numero in base 10 finché può, e lo ritorna. Se c'è
qualcosa dopo (altri caratteri) semplicemente li ignora */
quindi se hai "video 42 pippo.avi"
al primo passaggio avrai "42 pippo.avi"
e al secondo ritorna 42 (come long)
a questo punto immagino che questo numero vorrai usarlo per
riformattare il nome in qualcosa come "042 - il mio bel video.avi",
cosa che puoi fare con una:
printf("%03d - il mio bel video.avi", numero);
ovviamente il fulcro della cosa è la funzione strtol (una man page
qui: 
http://www.manpagez.com/man/3/strtol/
) - da qui ti leggi per bene
come funziona e come e quando gestire eventuali stringhe che escono
dallo schema atteso.
Ciao!
P.S. Se devi anche prendere le stringhe "di contorno", ovvero quello
che viene prima e dopo il numero, ti può aiutare sempre la stessa
funzione:
/* sempre senza controlli d'errore, modificando la stringa di input e
settando tre variabili esterne */
int find_numer_and_other(char *str, char **before, long *number, char
**after)
{
    char *tmp;
    *before = str; /* before inizia dove iniza la stringa */
    while(*str<'0' || *str>'9') ++str;
    tmp = str; /* salviamo il puntatore alla fine della prima stringa
*/
    *number = strtol(str, after, 10); /* prendiamo il numero, salvando
il puntatore alla seconda parte */
    *tmp = '\0'; /* aggiungiamo il terminatore stringa al primo pezzo
- NOTA: qui modifico la stringa di input */
    return 0; /* ritorno 0, nessun controllo = nessun errore */
}
Ri-ciao!

 non si potrebbero usare nel mio caso?
Si, c'e' la funzione rename in <stdio.h>
int rename( const char *old, const char *new );
ciao
Giacomo

 Chiedevo appunto per sapere se qualcuno sa risolverlo in maniera veloce... 
Sì, il problema mi sembra semplice. Credo che in mezz'oretta potrei 
realizzarlo...
E.

?manu* ha scritto:

Scusa l'ironia, vedo solo ora che effettivamente ti stai dando da fare 
per realizzarlo. L'unico altro suggerimento che ti posso dare è di 
cercare "man readdir" con google.
E.

ovviamente il fulcro della cosa è la funzione strtol (una man page
qui: 
http://www.manpagez.com/man/3/strtol/
) - da qui ti leggi per bene
come funziona e come e quando gestire eventuali stringhe che escono
dallo schema atteso.
Penso di aver capito, e prendendo spunto da tutti credo che riuscirò a 
farlo.
Ti chiedo solo un ultima cosa, i controlli d'errore che hai omesso 
riguardano
solo l'assenza di un numero nella stringa o c'è dell'altro?
Grazie e ancora ciao

 ha scritto nel 
messaggio 
news:25e17df5-2efb-45d4...@f8g2000yqn.googlegroups.com...

Grazie! mi ricordavo che c'era qualcosa.
Alla prossima 

 Grazie e ancora ciao
Ciao!

Ok! perfetto.
Ri-grazie ancora
Ciao ciao