Pagina 1 di 2
C+linux
Inviato: sab 4 apr 2009, 15:56
da Crow
ciao a tutti sto facendo delle prove, ho un frammento di codice che non mi va in poche parole ho fatto questo
Codice: Seleziona tutto
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int fdin, i, n,;
char *buf;
fdin=open("FILE3", O_RDONLY); //Crea FILE1
i=lseek(fdin,0,SEEK_CUR);
read(fdin,buf,8);
write(1,buf,8)
exit(0);
}
vorrei capire come mai non mi stampa i caratteri che sono scritti in FILE3 sullo stand. output cioè a video invece mi stampa
$ ./copia2
UåWVSè0
scusate la mia ignoranza in materia e grazie in anticipo per il vostro aiuto.
Re: C+linux
Inviato: sab 4 apr 2009, 15:58
da targzeta
buf non è allocato
Spina
Re: C+linux
Inviato: sab 4 apr 2009, 16:08
da Crow
ciao spina da quanto tempo mi fa piacere sentirti, hai detto che buf non è allocata solo che mi dovresti dire come fare se possibile perchè non ho capito cosa fare
grazie per la riposta
Re: C+linux
Inviato: sab 4 apr 2009, 16:12
da targzeta
Visto che leggi 8 caratteri fai:
Inoltre la seek è inutile e la read e la write devi invocarle passandogli &buff.
Spina
Re: C+linux
Inviato: sab 4 apr 2009, 16:22
da Crow
in pratica utilizzo lseek per spostarmi nel file per vedere come funziona ci sono due processi che scrivono all'interno di FILE3.
in pratica il codice che ho postato non è tutto.
ma è obbligatorio allocare in memoria, cioè non dovrebbe essere in compilatore a occuparsi di tutto ciò alla fine è solo un stringa di caratteri.
Codice: Seleziona tutto
la read e la write devi invocarle passandogli &buff.
gli devo passare obbligatoriamente l'indirizzo di memoria in questo semplice programmino?
confido nelle tue spiegazione, grazie

Re: C+linux
Inviato: sab 4 apr 2009, 16:31
da targzeta
Crow ha scritto:
in pratica utilizzo lseek per spostarmi nel file per vedere come funziona ci sono due processi che scrivono all'interno di FILE3.
in pratica il codice che ho postato non è tutto.
Si ma 0 insieme a SET_CUR non ha senso, vedi 'man lseek'.
Crow ha scritto:
ma è obbligatorio allocare in memoria, cioè non dovrebbe essere in compilatore a occuparsi di tutto ciò alla fine è solo un stringa di caratteri.
Il compilatore alloca memoria se tu gli dici di allocarla. char *buf alloca memoria per un puntatore a carattere. char buf[8] alloca 8 char.
Crow ha scritto:
Codice: Seleziona tutto
la read e la write devi invocarle passandogli &buff.
gli devo passare obbligatoriamente l'indirizzo di memoria in questo semplice programmino?
Il programma può essere semplice ho difficile ma la read e la write richiedono un puntatore e tu devi passargli un puntatore! Ma forse in questo caso (che non ho provato) puoi (o devi) dargli buf, dato che buf è un array e il nome dell'array è il puntatore alla prima locazione.
Prova e fammi sapere,
Spina
Re: C+linux
Inviato: sab 4 apr 2009, 17:29
da Mario Vanoni
Controlla il tuo codice sorgente con
gcc -fsyntax-only -Wstrict-prototypes -Wall codice.c
qualche volta e` molto utile.
Re: C+linux
Inviato: sab 4 apr 2009, 17:45
da robbybby
K&R, questi sconosciuti.

Re: C+linux
Inviato: sab 4 apr 2009, 17:49
da Mario Vanoni
robbybby ha scritto:K&R, questi sconosciuti.

DMR e` del 1941, puro caso, la mia annata.
Re: C+linux
Inviato: sab 4 apr 2009, 18:07
da targzeta
Mario Vanoni ha scritto:...DMR e` del 1941, puro caso, la mia annata.
Si ma si sa, ci sono vini buoni e vini meno buoni
Spina
Re: C+linux
Inviato: dom 5 apr 2009, 16:04
da Crow
Codice: Seleziona tutto
Il programma può essere semplice ho difficile ma la read e la write richiedono un puntatore e tu devi passargli un puntatore!
forse in questo caso no perchè buf è l'array per cui la read legge i caratteri e mette in buf, ho provato solo a cambiare *buf in buf[8] è andato tutto ok.
infatti
Codice: Seleziona tutto
:~$ gcc -fsyntax-only -Wstrict-prototypes -Wall copia2.c
non mi da nessun errore.
adesso però dovrei fare un'altra domanda, se in quel file ho 14 caratteri(compresi gli spaci bianchi) cioè in FILE3 ci sta scritto io sono a casa
Codice: Seleziona tutto
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define M 30
int main(void)
{
int fdin, i;
char buf[M];
fdin=open("FILE3", O_RDONLY); //Crea FILE1
i=lseek(fdin,0,SEEK_CUR);
read(fdin,buf,20);
write(1,buf,20);
exit(0);
}
compilo ed eseguo mi esce
~$ ./copia2
io sono a casôsentenza@slack:~$
se nella read e write metto come byte letti e scritti 14 mi esce
$ ./copia2
io sono a casasentenza@slack:~$
come mai? e poi ho notato un'altra cosa con la printf per fare andare a capo in cursore si usa \n con la write?
cioè io adesso ho sto output
$ ./copia2
io sono a casasentenza@slack:~$
se vorrei
$ ./copia2
io sono a casa
sentenza@slack:~$
questo con la printf basta un \n e con write.
ho provato ad fare questo in FILE3 sono andato a capo dopo aver scritto io sono a casa e invece di leggere e scrivere 14 caratteri ho voluto specificare 15 nella read e write è giusto fare così o ci sta un metodo più tecnico.
grazie a tutti per le risposte.
Re: C+linux
Inviato: dom 5 apr 2009, 16:46
da Mario Vanoni
char buf[14];
avra` 13 caratteri piu` lo "\0" finale per chiudere,
quindi _sempre_ (K&R)
char buf[M + 1];
EDIT:
Curiosita`:
perche` open(2) invece di fopen(3) ecc.?
Re: C+linux
Inviato: dom 5 apr 2009, 17:44
da absinthe
Crow ha scritto:Codice: Seleziona tutto
Il programma può essere semplice ho difficile ma la read e la write richiedono un puntatore e tu devi passargli un puntatore!
forse in questo caso no perchè buf è l'array per cui la read legge i caratteri e mette in buf, ho provato solo a cambiare *buf in buf[8] è andato tutto ok.
infatti
Codice: Seleziona tutto
:~$ gcc -fsyntax-only -Wstrict-prototypes -Wall copia2.c
non mi da nessun errore.
veramente hai passato l'indirizzo dell'array ovvero hai fatto ciò che ti ha detto spina. se crei un array e poi lo passi ad una funzione stai usando il puntatore al primo elemento allocato di tale array.
M
Re: C+linux
Inviato: dom 5 apr 2009, 18:12
da robbybby
Per leggere tutto il file, fino alla fine, senza perdere nemmeno un carattere, e senza leggerne neanche uno in piu', e senza avere un overflow sul tuo buffer, puoi fare cosi':
Codice: Seleziona tutto
#include <stdio.h>
#include <assert.h>
#define MAX_LEN 40
int main()
{
FILE *fp = NULL;
char szBuf[MAX_LEN + 1] = {'\0'}; //inserisce il NULL terminator come primo elemento
int iReadCnt = 0;
fp = fopen("miofile.txt",
"r"); //apri file in lettura
if(fp == NULL) //file aperto correttamente?
return 1; //no, esci con codice di errore
while(!feof(fp) && !ferror(fp)) //leggi fino alla fine del file, o fino a che avviene un errore
{
iReadCnt = fread(szBuf,
sizeof(char),
MAX_LEN,
fp);
if(iReadCnt > 0)
fwrite(szBuf,
sizeof(char),
iReadCnt,
stdout);
}
assert(fp);
fclose(fp);
return 0; //segnala tutto ok
}
Allo studente e' lasciato il compito di comprendere il perche' dei vari passaggi

Si noti solo l'inizializzazione di TUTTE le variabili.
Re: C+linux
Inviato: dom 5 apr 2009, 19:47
da Mario Vanoni
robbybby ha scritto:
assert(fp);
fclose(fp);
Allo studente e' lasciato il compito di comprendere il perche' dei vari passaggi
Domanda di uno studente di 68 anni:
a cosa serve un assert(3) prima di un fclose(3)
di cui non si controlla il/la RETURN VALUE?