Prethodna tema :: Sljedeća tema |
Autor/ica |
Poruka |
Crni Forumaš(ica)


Pridružen/a: 15. 12. 2003. (01:20:43) Postovi: (23C)16
Spol: 
Lokacija: Zagreb
|
Postano: 17:07 sub, 10. 4. 2004 Naslov: stringovi & v-liste |
|
|
[code:1]typedef struct lista
{
char* s;
struct lista *n;
} lista;
lista* kraj (lista *g)
{
lista *p,*k;
for (p=g; p!=NULL; p=p->n)
k=p;
return k;
}
lista* unos (lista *g)
{
lista *p,*k;
p=(lista *) malloc(sizeof(lista));
p->s=(char *) malloc(129*sizeof(char));
printf("unesite string: ");
scanf("%s",p->s);
p->n=NULL;
if (g==NULL)
return p;
else
{
k=kraj(g);
k->n=p;
return g;
}
}[/code:1]
Je li moguće učitat string proizvoljne duljine bez ograničenja (kako piše u navedenom kodu) na duljinu?
Ustvari bi htel' rezervirat' točno onu količinu memorije za string-ćeliju, kolika iznosi za string koji učitam, a da opet nemam ograničenja na duljinu učitanog stringa. Ima li ne'ko ideju?
Kod: | typedef struct lista
{
char* s;
struct lista *n;
} lista;
lista* kraj (lista *g)
{
lista *p,*k;
for (p=g; p!=NULL; p=p->n)
k=p;
return k;
}
lista* unos (lista *g)
{
lista *p,*k;
p=(lista *) malloc(sizeof(lista));
p->s=(char *) malloc(129*sizeof(char));
printf("unesite string: ");
scanf("%s",p->s);
p->n=NULL;
if (g==NULL)
return p;
else
{
k=kraj(g);
k->n=p;
return g;
}
} |
Je li moguće učitat string proizvoljne duljine bez ograničenja (kako piše u navedenom kodu) na duljinu?
Ustvari bi htel' rezervirat' točno onu količinu memorije za string-ćeliju, kolika iznosi za string koji učitam, a da opet nemam ograničenja na duljinu učitanog stringa. Ima li ne'ko ideju?
|
|
[Vrh] |
|
GauSs_ Moderator


Pridružen/a: 28. 01. 2004. (21:01:17) Postovi: (53C)16
Spol: 
Lokacija: 231
|
|
[Vrh] |
|
Crni Forumaš(ica)


Pridružen/a: 15. 12. 2003. (01:20:43) Postovi: (23C)16
Spol: 
Lokacija: Zagreb
|
|
[Vrh] |
|
Void Forumaš(ica)

Pridružen/a: 14. 11. 2002. (18:08:22) Postovi: (FA)16
|
|
[Vrh] |
|
Crni Forumaš(ica)


Pridružen/a: 15. 12. 2003. (01:20:43) Postovi: (23C)16
Spol: 
Lokacija: Zagreb
|
|
[Vrh] |
|
vsego Site Admin


Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3562)16
Spol: 
Lokacija: /sbin/init
|
Postano: 20:24 ned, 11. 4. 2004 Naslov: |
|
|
Nisam bas neki C-guru, ali mozes ucitavati blokove neke velicine (recimo, prema Voidovom naputku) i konkatenirati ih. :shock: Dodatnu memoriju zauzmes s funkcijom realloc(). 8) Iz mana:
[code:1]void *realloc(void *ptr, size_t size);
realloc() changes the size of the memory block pointed to by ptr to
size bytes. The contents will be unchanged to the minimum of the old
and new sizes; newly allocated memory will be uninitialized. If ptr is
NULL, the call is equivalent to malloc(size); if size is equal to zero,
the call is equivalent to free(ptr). Unless ptr is NULL, it must have
been returned by an earlier call to malloc(), calloc() or realloc().
realloc() returns a pointer to the newly allocated memory, which is
suitably aligned for any kind of variable and may be different from
ptr, or NULL if the request fails. If size was equal to 0, either NULL
or a pointer suitable to be passed to free() is returned. If realloc()
fails the original block is left untouched - it is not freed or moved.[/code:1]
:verycool:
Nisam bas neki C-guru, ali mozes ucitavati blokove neke velicine (recimo, prema Voidovom naputku) i konkatenirati ih. Dodatnu memoriju zauzmes s funkcijom realloc(). Iz mana:
Kod: | void *realloc(void *ptr, size_t size);
realloc() changes the size of the memory block pointed to by ptr to
size bytes. The contents will be unchanged to the minimum of the old
and new sizes; newly allocated memory will be uninitialized. If ptr is
NULL, the call is equivalent to malloc(size); if size is equal to zero,
the call is equivalent to free(ptr). Unless ptr is NULL, it must have
been returned by an earlier call to malloc(), calloc() or realloc().
realloc() returns a pointer to the newly allocated memory, which is
suitably aligned for any kind of variable and may be different from
ptr, or NULL if the request fails. If size was equal to 0, either NULL
or a pointer suitable to be passed to free() is returned. If realloc()
fails the original block is left untouched - it is not freed or moved. |
_________________ U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju. 
|
|
[Vrh] |
|
Void Forumaš(ica)

Pridružen/a: 14. 11. 2002. (18:08:22) Postovi: (FA)16
|
Postano: 23:07 ned, 11. 4. 2004 Naslov: |
|
|
[quote="Crni"][quote="Void"]Prvo si deklariras neku pomocnu string varijablu i ucitas u nju
[code:1]
char s[NAJVECA_MOGUCA_DULJINA+1];
scanf("%s", s);
[/code:1][/quote]
Da OK, ali štos je u tome da ja ne želim ovo ograničenje kaj se zove NAJVECA_MOGUCA_DULJINA+1[/quote]
Ne vidim cemu tolika averzija prema ovome ogranicenju. Recimo da je za prakticne primjene NAJVECA_MOGUCA_DULJINA jednaka 1000. Onda imas 1000 byteova memorije koje ti pomaze da dobijes na ekonomican nacin koliko god ti treba i nimalo vise.
Ako stvarno ne zelis to ogranicenje, onda mozes stringove ucitavati znak po znak i za svaki znak posebno rezervirati memoriju. Tj, string ces predstaviti unutar vezane liste kao vezanu listu. Ako ti trebaju naputci kako to iskodirati, budem poslao.
Crni (napisa): | Void (napisa): | Prvo si deklariras neku pomocnu string varijablu i ucitas u nju
Kod: |
char s[NAJVECA_MOGUCA_DULJINA+1];
scanf("%s", s);
|
|
Da OK, ali štos je u tome da ja ne želim ovo ograničenje kaj se zove NAJVECA_MOGUCA_DULJINA+1 |
Ne vidim cemu tolika averzija prema ovome ogranicenju. Recimo da je za prakticne primjene NAJVECA_MOGUCA_DULJINA jednaka 1000. Onda imas 1000 byteova memorije koje ti pomaze da dobijes na ekonomican nacin koliko god ti treba i nimalo vise.
Ako stvarno ne zelis to ogranicenje, onda mozes stringove ucitavati znak po znak i za svaki znak posebno rezervirati memoriju. Tj, string ces predstaviti unutar vezane liste kao vezanu listu. Ako ti trebaju naputci kako to iskodirati, budem poslao.
|
|
[Vrh] |
|
Crni Forumaš(ica)


Pridružen/a: 15. 12. 2003. (01:20:43) Postovi: (23C)16
Spol: 
Lokacija: Zagreb
|
|
[Vrh] |
|
Zvone Forumaš(ica)

Pridružen/a: 01. 07. 2003. (13:09:44) Postovi: (9D)16
|
Postano: 1:08 pon, 12. 4. 2004 Naslov: |
|
|
A lijepo je vsego rekao da pogledas realloc...
No dobro, evo kod koji ce ucitati string proizv. duljine u komadicima od po 10 znakova (ovih 10 je proizvoljno, naravno, mozes ucitavati po 10000 ako zelis):
[code:1]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void )
{
char *veliki=NULL;
char buffer[11];
int duljina=0, stara_duljina;
do
{
stara_duljina=duljina;
scanf ("%10[^ ^\n]", buffer); buffer[10]='\0';
if ((veliki=realloc (veliki, duljina+=strlen (buffer))) == NULL)
{
printf ("Out of memory!\n");
exit (1);
}
strcpy (veliki+stara_duljina, buffer);
} while (duljina-stara_duljina == 10);
printf ("[%s]\n", veliki);
return 0;
}
[/code:1]
Ona cudna linija sa scanf ucitava 10 znakova ili staje kad naleti na razmak ili kraj reda.
Ne znam jesam li gdje fulao, ali bitan je koncept...koliko god memorije unaprijed alocirao za svoj veliki string, korisnik uvijek moze unijeti 1 znak vise, pa mi se cini da ne preostaje nista drugo nego raditi nesto slicno ovom sto sam napisao...
A lijepo je vsego rekao da pogledas realloc...
No dobro, evo kod koji ce ucitati string proizv. duljine u komadicima od po 10 znakova (ovih 10 je proizvoljno, naravno, mozes ucitavati po 10000 ako zelis):
Kod: |
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void )
{
char *veliki=NULL;
char buffer[11];
int duljina=0, stara_duljina;
do
{
stara_duljina=duljina;
scanf ("%10[^ ^\n]", buffer); buffer[10]='\0';
if ((veliki=realloc (veliki, duljina+=strlen (buffer))) == NULL)
{
printf ("Out of memory!\n");
exit (1);
}
strcpy (veliki+stara_duljina, buffer);
} while (duljina-stara_duljina == 10);
printf ("[%s]\n", veliki);
return 0;
}
|
Ona cudna linija sa scanf ucitava 10 znakova ili staje kad naleti na razmak ili kraj reda.
Ne znam jesam li gdje fulao, ali bitan je koncept...koliko god memorije unaprijed alocirao za svoj veliki string, korisnik uvijek moze unijeti 1 znak vise, pa mi se cini da ne preostaje nista drugo nego raditi nesto slicno ovom sto sam napisao...
|
|
[Vrh] |
|
vsego Site Admin


Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3562)16
Spol: 
Lokacija: /sbin/init
|
Postano: 17:16 pon, 12. 4. 2004 Naslov: |
|
|
[code:1] scanf ("%10[^ ^\n]", buffer); buffer[10]='\0';[/code:1]
:shock: :shock: :shock: [b]TO[/b] se moze?!? Ima negdje on-line info sto sve to cudo od scanf() "guta"?
[code:1] if ((veliki=realloc (veliki, duljina+=strlen (buffer))) == NULL)
{
printf ("Out of memory!\n");
exit (1);
}
[/code:1]
Malo :OT: Kad napravis exit(), da li ce program vratiti prethodno alociranu memoriju ili treba prvo pozvati free(), pa tek onda exit()? :-k
Thanx! 8)
P.S. I ja onda drzim vjezbe iz C-a... :oops:
Kod: | scanf ("%10[^ ^\n]", buffer); buffer[10]='\0'; |
TO se moze?!? Ima negdje on-line info sto sve to cudo od scanf() "guta"?
Kod: | if ((veliki=realloc (veliki, duljina+=strlen (buffer))) == NULL)
{
printf ("Out of memory!\n");
exit (1);
}
|
Malo Kad napravis exit(), da li ce program vratiti prethodno alociranu memoriju ili treba prvo pozvati free(), pa tek onda exit()?
Thanx!
P.S. I ja onda drzim vjezbe iz C-a...
_________________ U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju. 
|
|
[Vrh] |
|
ahri Forumaš(ica)


Pridružen/a: 19. 11. 2003. (23:16:07) Postovi: (193)16
|
Postano: 18:46 pon, 12. 4. 2004 Naslov: |
|
|
[quote="vsego"][code:1] scanf ("%10[^ ^\n]", buffer); buffer[10]='\0';[/code:1]
:shock: :shock: :shock: [b]TO[/b] se moze?!? Ima negdje on-line info sto sve to cudo od scanf() "guta"?
[/quote]
ajme...
btw, buffer[11]
[quote]
[code:1] if ((veliki=realloc (veliki, duljina+=strlen (buffer))) == NULL)
{
printf ("Out of memory!\n");
exit (1);
}
[/code:1]
Malo :OT: Kad napravis exit(), da li ce program vratiti prethodno alociranu memoriju ili treba prvo pozvati free(), pa tek onda exit()? :-k
Thanx! 8)
P.S. I ja onda drzim vjezbe iz C-a... :oops:[/quote]
bas i ja kazem...
:)))
man scanf ;)
nemoras frijat.
vsego (napisa): | Kod: | scanf ("%10[^ ^\n]", buffer); buffer[10]='\0'; |
:shock: :shock: :shock: TO se moze?!? Ima negdje on-line info sto sve to cudo od scanf() "guta"?
|
ajme...
btw, buffer[11]
Citat: |
Kod: | if ((veliki=realloc (veliki, duljina+=strlen (buffer))) == NULL)
{
printf ("Out of memory!\n");
exit (1);
}
|
Malo :OT: Kad napravis exit(), da li ce program vratiti prethodno alociranu memoriju ili treba prvo pozvati free(), pa tek onda exit()? :-k
Thanx! 8)
P.S. I ja onda drzim vjezbe iz C-a... :oops: |
bas i ja kazem...
:)))
man scanf ;)
nemoras frijat.
_________________ 
|
|
[Vrh] |
|
Crni Forumaš(ica)


Pridružen/a: 15. 12. 2003. (01:20:43) Postovi: (23C)16
Spol: 
Lokacija: Zagreb
|
|
[Vrh] |
|
Zvone Forumaš(ica)

Pridružen/a: 01. 07. 2003. (13:09:44) Postovi: (9D)16
|
Postano: 20:03 sri, 14. 4. 2004 Naslov: |
|
|
[quote]Ima negdje on-line info sto sve to cudo od scanf() "guta"[/quote]
Ne znam, nisam bas trazio...u helpu od MSVC-a ( :shock: ), tj. MSDNu ima dosta toga objasnjeno, ja obicno tamo pogledam kad mi je nesto cudno :)
[quote]Kad napravis exit(), da li ce program vratiti prethodno alociranu memoriju ili treba prvo pozvati free(), pa tek onda exit()? [/quote]
Hmmm...ali ako je realloc vratio NULL, to znaci da smo zapravo izgubili pointer koji je pokazivao na stari blok memorije, pa bi pozivanje free(veliki) bio pokusaj dealokacije NULL-pointera, sto bas i nije dozvoljeno... To bi se mozda moglo rijesiti tako da zapamtimo gdje je prije realloca pokazivao veliki, ali je malo nejasno sta se sa tim dijelom memorije dogodi nakon poziva realloc? Da vidimo sto kaze MSDN:
[quote]realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged.[/quote]
Evo, sad je jasno, dakle treba zapamtit stari pointer i prije exit-a free-at...bravo MSDN :)
(P.S. Sad sam skuzio da to zapravo pise i u man-u od realloca kojeg je citirao vsego...bravo man :) )
[quote]Hmm..zna li netko zakaj učitavanje stringa ne dozvoljava razmake i kak' se može sredit da dozvoljava?[/quote]
Evo jos jednom:
[code:1]char s[100];
scanf ("%[^\n]", s);
[/code:1]
cita sve dok ne naleti na oznaku za kraj reda (ukljucujuci i razmake!) i to sto je procitao spremi u s. Naravno, da procitas sve do npr. zareza trebas napisati
[code:1]scanf ("%[^,]", s); [/code:1]
a ako npr. zelis citati samo znakove abfegHTA, zarez i razmak i stati kad se procita prvi znak koji nije iz tog skupa treba napisati
[code:1]scanf ("%[abfegHTA, ]", s); [/code:1]
Ako zelis npr. citati samo slova, mozes umjesto da ih sva nabrojis napisati jednostavno
[code:1]scanf ("%[A-Za-z]", s); [/code:1]
Uobicajeni scanf ("%s", s) je zapravo isto sto i scanf ("%[^ \n]", s);
Citat: | Ima negdje on-line info sto sve to cudo od scanf() "guta" |
Ne znam, nisam bas trazio...u helpu od MSVC-a ( ), tj. MSDNu ima dosta toga objasnjeno, ja obicno tamo pogledam kad mi je nesto cudno
Citat: | Kad napravis exit(), da li ce program vratiti prethodno alociranu memoriju ili treba prvo pozvati free(), pa tek onda exit()? |
Hmmm...ali ako je realloc vratio NULL, to znaci da smo zapravo izgubili pointer koji je pokazivao na stari blok memorije, pa bi pozivanje free(veliki) bio pokusaj dealokacije NULL-pointera, sto bas i nije dozvoljeno... To bi se mozda moglo rijesiti tako da zapamtimo gdje je prije realloca pokazivao veliki, ali je malo nejasno sta se sa tim dijelom memorije dogodi nakon poziva realloc? Da vidimo sto kaze MSDN:
Citat: | realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. |
Evo, sad je jasno, dakle treba zapamtit stari pointer i prije exit-a free-at...bravo MSDN
(P.S. Sad sam skuzio da to zapravo pise i u man-u od realloca kojeg je citirao vsego...bravo man )
Citat: | Hmm..zna li netko zakaj učitavanje stringa ne dozvoljava razmake i kak' se može sredit da dozvoljava? |
Evo jos jednom:
Kod: | char s[100];
scanf ("%[^\n]", s);
|
cita sve dok ne naleti na oznaku za kraj reda (ukljucujuci i razmake!) i to sto je procitao spremi u s. Naravno, da procitas sve do npr. zareza trebas napisati
a ako npr. zelis citati samo znakove abfegHTA, zarez i razmak i stati kad se procita prvi znak koji nije iz tog skupa treba napisati
Kod: | scanf ("%[abfegHTA, ]", s); |
Ako zelis npr. citati samo slova, mozes umjesto da ih sva nabrojis napisati jednostavno
Kod: | scanf ("%[A-Za-z]", s); |
Uobicajeni scanf ("%s", s) je zapravo isto sto i scanf ("%[^ \n]", s);
|
|
[Vrh] |
|
|