View Full Version : [C] ..e le stringhe?!?
leadergl
19-10-2005, 15:27
raga mi sto da pochissimo avvicinando al C ma già programmo in Turbo Pascal, Visual Basic 6 ed un po di .Net e di derivazione anche Delphi 7...
in tutti questi linguaggi esiste la definizione di variabile stringa:"string" ma in C questa non c'è...
ora mi sta bene dichiarare le stringhe come array di caratteri MA se devo leggere un intero rigo di un file per poi analizzarlo come faccio?!
Per dichiarare un'array gli devo dare una lunghezza tipo:
char Nome[14];
giusto?
ma io come faccio a sapere a priori la lunghezza della riga da leggere?
qualcuno mi dice la procedura che si usa in C per leggere una intera riga da file?
grazie mille ;)
DanieleC88
19-10-2005, 16:10
In quel modo hai dichiarato un'array caratteri di grandezza fissa. Per avere un'array di caratteri di lunghezza indeterminata, devi usare un puntatore, quindi:
char * stringa;
E gestire la sua allocazione (malloc) il suo ridimensionamento (realloc) e l'eliminazione (free). Benvenuto nel mondo del C! ;) :D
ilsensine
19-10-2005, 16:11
Usa fgets, con un buffer di dimensione ragionevole.
Se le tue righe possono avere dimensioni abnormi, devi cambiare tecnica (ad es. mmap), oppure leggere un byte alla volta.
leadergl
19-10-2005, 16:25
ok mettiamo che per qualche ragione io devo leggere e memorizzare in una variabile un intero file!
facciamo che il file abbia 10 righe...
come si fa?
potreste scrivere un po di codice?
ilsensine
19-10-2005, 17:27
Il metodo classico è allocare un buffer grande quanto l'intero file, e leggerlo dentro. E' un metodo triviale ma poco efficiente, soprattutto se il file è grande e hai poca memoria. Meglio mappare il file nello spazio di indirizzi del processo.
Ad esempio questo programma mappa un file, e lo stampa un carattere alla volta (è per linux/unix, ma ti rende l'idea):
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int fd;
struct stat st;
char *map;
int x;
if (argc<2) {
printf("%s <file>\n", argv[0]);
return -1;
}
fd = open(argv[1], O_RDONLY);
if (fd<0) {
perror("open");
return -1;
}
fstat(fd, &st);
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map==MAP_FAILED) {
perror("mmap");
return -1;
}
close(fd);
for (x=0; x<st.st_size; ++x)
printf("%c", map[x]);
munmap(map, st.st_size);
return 0;
}
leadergl
19-10-2005, 20:00
niente di meno quello che nei 3 linguaggi che conosco si fa con:
VB6:
dim variabile_destinazione as string
dim rigo_letto as string
open "c:\esempio.txt" for input as #1
while not eof(1)
input #1, rigo_letto
variabile_destinazione=variabile_destinazione+rigo_letto
wend
close #1
PASCAL:
Var file:text;
rigo:string;
carattere:char;
assign('c:\esempio.txt',file);
reset(file);
while not eof (file) do
begin
read(carattere,file);
rigo=rigo + carattere;
end;
(scritto alla buona :p )
si trasforma in tutto quel casino?!? non ci voglio credere :doh:
non esiste un modo più semplice?
prova a contare quanti bytes occupa il file(in una var int)es alloca un'array di caratteri di tali dimensioni....
ilsensine
20-10-2005, 08:55
niente di meno quello che nei 3 linguaggi che conosco si fa con:
si trasforma in tutto quel casino?!? non ci voglio credere :doh:
Ehm non è la stessa cosa. Quello che ti ho postato (che non è affatto difficile) è un procedimento molto più efficiente rispetto ai tuoi esempi.
non esiste un modo più semplice?
Ok vuoi il modo "triviale". Anche questo scritto alla" buona":
FILE *f = fopen("esempio.txt", "rb");
struct stat st;
char *variabile;
stat("esempio.txt", &st);
variabile = calloc(st.st_size+1, 1);
fread(variabile, 1, st.st_size, f);
fclose(f);
cdimauro
20-10-2005, 10:02
In Python:
f = open('pippo.dat')
s = f.read()
f.close()
print s
;)
ilsensine
20-10-2005, 12:29
In Python:
f = open('pippo.dat')
s = f.read()
f.close()
print s
;)
In Bash:
foo=`cat pippo.dat`
:ciapet:
cdimauro
21-10-2005, 10:11
:rotfl:
:D :mano:
Ok vuoi il modo "triviale". Anche questo scritto alla" buona":
FILE *f = fopen("esempio.txt", "rb");
struct stat st;
char *variabile;
stat("esempio.txt", &st);
variabile = calloc(st.st_size+1, 1);
fread(variabile, 1, st.st_size, f);
fclose(f);
free(variabile);
ok le cose alla buona, ma non diamogli brutti vizi :asd:
leadergl
21-10-2005, 12:06
io non voglio le cose alla buona ma è che di C non so ancora nulla, sto imparando...e non capisco perchè si fa tutto questo casino per leggere da un file....boh....
cmq per la procedura alla buona direi:
1) aprire file in lettura
2) redimensionare spazio di memoria in cui memorizzare
3) leggere il carattere
4) ripetere le operazioni 2 e 3 finchè non finisce il rigo o il file
5) chiudere il file
giusto?
mentre la versione "estesa", ovvero quella fatta come si deve, che faceva nel dettaglio?
ilsensine
21-10-2005, 13:09
Ancora non ho capito se vuoi:
1 - leggere tutto il file in memoria
2 - leggerlo per righe (potendo assumere una dimensione ragionevole per le righe)
3 - leggerlo per righe ma potendo gestire righe anche di 736823763 caratteri...
Credo che con fgets, come ti ho suggerito, puoi gestire facilmente il 2. Per 1, ti ho dato due soluzioni (una elegante, l'altra non molto dissimile ai tuoi esempi). Rimane 3, che sinceramente non serve a niente.
leadergl
21-10-2005, 13:32
mi interessano la 1 e la 3.
ma credo quella importante sia la 3...perchè implica un po la 1...
ilsensine
21-10-2005, 13:40
Allora fai il contrario, no? Leggi (suggerirei: mappi) il file in memoria, e da lì tiri fuori le righe. Non capisco cosa c'è di difficile...
leadergl
21-10-2005, 13:55
il difficile è che al momento ho dimestichezza 0 col C e come teoria sto alla dichiarazione dei vettori....!!
è questo il difficile...quindi mentre in Pascal, Delphi o VB se succede un errore riesco subito a trovare il perchè e se non riesco a fare una cosa in un modo la faccio in un altro..beh in C questa flessibilità non la ho perchè non conosco niente del C...e nel tuo codice vedo strutture che ancora non conosco e che non hanno un riscontro visivo immediato negli altri linguaggi:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
int fd;
struct stat st;
char *map;
int x;
if (argc<2) {
printf("%s <file>\n", argv[0]);
return -1;
}
fd = open(argv[1], O_RDONLY);
if (fd<0) {
perror("open");
return -1;
}
fstat(fd, &st);
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map==MAP_FAILED) {
perror("mmap");
return -1;
}
close(fd);
for (x=0; x<st.st_size; ++x)
printf("%c", map[x]);
munmap(map, st.st_size);
return 0;
}
questo è quello che mi hai scritto per mappare tutto il file in memoria MA:
struct stat st;
che struttura è?
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
a che servono tutte ste librerie?
fd = open(argv[1], O_RDONLY);
questa credo serva ad aprire il file in sola lettura e farlo puntare da "fd"...credo...
if (argc<2) {
printf("%s <file>\n", argv[0]);
return -1;
}
che cavolo è "argc"? a che serve? inoltre si possono passare argomenti alla main senza che questa venga in realtà chiamata da nessuno?!?
fstat(fd, &st);
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
e queste due funzioni?!?
"fstat" a che serve?
"mmap" credo copii l'intero file in memoria...boh?!?
"munmap" credo elimini il file dalla memoria...boh?!
come puoi vedere questi sono un sacco di punti che per uno che si avvicina al C sono un po contorti...
io ho portato l'esempio degli linguaggi perchè semplicemente conoscendo le stringhe (dichiarazione comune di una variabile) e la funzione per "aprire" e "leggere" da un file si risolve tutto....mentre in C è un casino (e sinceramente nn capisco xkè un linguaggio così potente abbia un modo così contorto per leggere da file e non disponga della variabile stringa che è troppo comoda....
se sei sotto UNIX[linux o mac os x] basta che apri un terminale e fai: man <nome_funzione>e scopri tutto..altrimenti fai una ricerca su google per le funzioni...ora devo andare a lezione e non posso spiegarti sorry :D
ilsensine
21-10-2005, 15:46
<...>
Era solo un esempio per farti capire il concetto, speravo che capissi.
come puoi vedere questi sono un sacco di punti che per uno che si avvicina al C sono un po contorti...
E' questo il problema, non conosci abbastanza come ragiona il c...
I linguaggi che hai portato ad esempio sono tutti linguaggi ad oggetti; forse con il c++ potresti trovarti più a tuo agio, ci sono già molti oggetti pronti che possono esserti di aiuto, ma non credere che imparare ad usarlo bene sia più facile...
Non so quello che devi fare; se è per un esame, prendi la strada più semplice (fgets).
leadergl
21-10-2005, 17:00
no, io ho capito quello che cercavi di dirmi col primo algoritmo ed è quello che cercavo...nel senso, mi spiego, sapere come si legge da file non mi serve per nessun esercizio universitario o per fare qualche esame al momento...ma siccome sto seguendo il corso di Algoritmi e Strutture Dati ma sopratutto il LABORATORIO di ASD ho bisogno di conoscere il C...così mentre il prof. (x ki come me ha fatto pascal) fa una rapida descrizione delle varie cose (if, while, array..etc..) io vorrei cercare di impararlo per bene questo linguaggio...
ovvio che non mi basta un giorno o una settimana perchè ci devo prendere dimestichezza e devo capire il modo in cui il C tratta TUTTO però voglio impararlo ed ovviamente mi son fatto delle domande, la più banale era questa sui files che non mi spiegavo come leggere un file in maniera rapida e semplice (o sempliciotta) senza l'uso di una struttura "stringa" vera e propria...
il mio intento era arrivare a quel codice che tu hai scritto ma che ovviamente a me in questo preciso momento dice poco per le mie scarse conoscenze di C (anzi nulle).
Ovvio che adesso dovrò vedermi il trattamento/uso di Array, Matrici, Puntatori in C e questo mi aprirà la strada alle Code/Liste/Alberi ed ai Files...visto che vedo uso di puntatori...però il mio intento è farle per bene le cose quindi il tuo algoritmo è perfetto ma mi serve un po per capirlo mentre una cosa un po più alla buona (come gli altri algoritmi semplificati) mi permettono un po di prendere familiarità ;)
cmq vi ringrazio per avermi risposto, thanks ;)
ilsensine
21-10-2005, 17:13
però il mio intento è farle per bene le cose quindi il tuo algoritmo è perfetto
Quale, quello con l'mmap? Ha ben poco di algoritmico, è solo una tecnica :D
la più banale era questa sui files che non mi spiegavo come leggere un file in maniera rapida e semplice (o sempliciotta) senza l'uso di una struttura "stringa" vera e propria
Sicuro che non vuoi iniziare col dare una occhiata al c++, dove hai a disposizione stringhe e quant'altro già pronti all'uso?
leadergl
21-10-2005, 20:58
beh allargare le mie conoscenze in questo senso è interessante però dovrei farlo in concomitanza con lo studio necessario/obbligatorio del C ;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.