Jak v C uložit do pole char pointer na další slovo – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak v C uložit do pole char pointer na další slovo – C / C++ – Fórum – Programujte.comJak v C uložit do pole char pointer na další slovo – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
MilanL+1
Grafoman
1. 9. 2020   #1
-
0
-

Ahoj,

řešil jsem úkol s vytvořením pole jednotlivých slov ve větě podle delimiteru.

řeším to 2 fázově nejdříve spočítám slova, alokuji char** na daný počet char* a poté počítám znaky slov a alokuji char* pro daný počet písmen a zkopíruji znaky.
 

přemýšlel jsem jak to zjednodušit, zda by nešlo přeskočit první fázi a jít rovnou do počítání znaků a kopírování s tím, že ve slově přidám do alokace místo na pointer na další slovo, ale nevím jak do char* dostat na ten konec za "\0" ten pointer, tedy obě cesty jak uložení tak přečtení.

něco jako spojitý seznam v jiném jazyce bych to nadefinoval např jako strukturu

{slovo : string ;
next : pointer;}

Nahlásit jako SPAM
IP: 185.112.167.–
KIIV
~ Moderátor
+43
God of flame
1. 9. 2020   #2
-
0
-

Pokud muzes ten prohledavany retezec menit, tak proste zapisujes \0 misto delimiteru a pokracujes na dalsim znaku. Jen si pak samozrejme pamatovat, ze tyhle podretezce ti nepatri a free se da udelat jen na ten uplne prvni jako celek.

Na seznam pointeru se hodi spise spojovy seznam. Ale s pomoci reallocu se to da zmaknout taky a v jednom kole.

Nahlásit jako SPAM
IP: 78.80.99.–
Program vždy dělá to co naprogramujete, ne to co chcete...
gna
~ Anonymní uživatel
1882 příspěvků
2. 9. 2020   #3
-
0
-

#1 MilanL
Nějak nechápu ten poslední dostavec. C taky "umí" struktury.

struct neco {
  typ jmeno;
  typ jmeno;
};
Nahlásit jako SPAM
IP: 213.211.51.–
MilanL+1
Grafoman
2. 9. 2020   #4
-
0
-

#3 gna
ano vím tomu jsem se chtěl ale vyhnou.

napadá mě řešení s přetypováním

char* slovo = malloc(počet znaků);
{ kopie slova }
char** next = (char**) slovo;   nebo to má být   *(next) = slovo; ?
najdi další slovo

slovo  = malloc(počet znaků);
next = slovo;

přiznám se trošku v těch pointerech plavu

Nahlásit jako SPAM
IP: 185.112.167.–
MilanL+1
Grafoman
2. 9. 2020   #5
-
0
-

no já si to tedy vyzkouším, různé varianty a snad to dopade

btw to už si rovnou můžu udělat kopii textu a nahradit delimitery v té kopii, nebo předem vytvořit pole pointerů ** určité velikosti a jen v případě překročení ho realokovat.

ještě mě tak napadá že ten next by měl být na začátku kvůli pozdějšímu uvolňování

Nahlásit jako SPAM
IP: 185.112.167.–
Řešení
gna
~ Anonymní uživatel
1882 příspěvků
2. 9. 2020   #6
-
+1
-
Zajímavé
Vyřešeno Nejlepší odpověď

 Jestli ti jde o to mít to v jedné alokaci, tak pořád můžeš použít strukturu. 

struct item {
	char *next;
	char data[1];
};

struct item *i = malloc(sizeof(struct item) + strlen(slovo));

To přidání za string by bylo takhle, ale nechápu proč bys to dělal.

char *buffer = malloc(delka_slova + 1 + sizeof(char *));
char *slovo = bufer;
... copy slovo ...

char **pnext = (char **) (slovo + strlen(slovo) + 1);
*pnext = next;
Nahlásit jako SPAM
IP: 213.211.51.–
gna
~ Anonymní uživatel
1882 příspěvků
2. 9. 2020   #7
-
0
-

Teda next v té struktuře by samozřejmě zase byla ta struktura. 

struct item {                                                                   
    struct item *next;                                                      
    char data[1];                                                           
};
Nahlásit jako SPAM
IP: 213.211.51.–
MilanL+1
Grafoman
2. 9. 2020   #8
-
0
-

#6 gna
oki díky moc za objasnění hlavně ta druhá část mi to trošku vyjasnila,

ještě otázka ten malock alokuje jen opravdu potřebnou paměť nebo blok s nějakou minimální velikostí, případně s paměťovým zarovnáním?

Nahlásit jako SPAM
IP: 185.112.167.–
gna
~ Anonymní uživatel
1882 příspěvků
2. 9. 2020   #9
-
0
-

Alokátory typicky interně podporují jen velikosti s nějakou granularitou, takže reálná alokovaná velikost bude vždycky s nějakým zarovnáním.

Nahlásit jako SPAM
IP: 213.211.51.–
Kit+15
Guru
2. 9. 2020   #10
-
0
-

#8 MilanL
mallock() alokuje tuším se zarovnáním na jedno slovo, tedy 4 nebo 8 bajtů dle arcarchitektury. Plus ještě jedno slovo režie. Alokace po několika bajtech není tedy efektivní.

Nechal bych slova v původním stringu, spočítal je a alokoval jedno pole pro indexy do toho původního stringu.

Zkus se podívat, jak to interně řeší jazyky Lisp a Forth, které jsou na slovnících založeny.

Nahlásit jako SPAM
IP: 46.135.12.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Kit+15
Guru
2. 9. 2020   #11
-
0
-

#8 MilanL
Tak jsem si to zmapoval. Když chci alokovat 1-24 bajtů, tak si malloc() vždy ukousne 32 B. Pro alokaci 25-40 B si vezme 48 B atd.

Alokace malých kousků RAM se prostě nevyplácí. Doporučuje se alokovat prostor pro celé pole a při potřebě změny velikosti udělat realloc() na dvojnásobnou, resp. poloviční velikost.

Nahlásit jako SPAM
IP: 46.135.12.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
MilanL+1
Grafoman
3. 9. 2020   #12
-
0
-

#11 Kit
souhlasím, včera jsem ty pointery vyřešil mám  to hotové bez struktury jen holé  

pointer1+slovo0 , pointer2+slovo1....pointer poslední+slovo předposlední , pointer=0 slovo poslední

samozřejmě s uložením startovního pointeru pro další práci a následné uvolnění

Nahlásit jako SPAM
IP: 91.139.9.–
gna
~ Anonymní uživatel
1882 příspěvků
3. 9. 2020   #13
-
0
-

#12 MilanL
Takže tu strukturu vyrábíš "ručním" čarováním s pointery, abys ušetřil práci překladači :-)

Nahlásit jako SPAM
IP: 213.211.51.–
Kit+15
Guru
3. 9. 2020   #14
-
0
-

#13 gna
Vytváření vlastních abstraktních datových struktur je náhodou dobrým cvičením.

Nahlásit jako SPAM
IP: 46.135.12.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
MilanL+1
Grafoman
3. 9. 2020   #15
-
0
-

Mě šlo vlastně o to zredukovat to několikanásobné procházení zdrojovým textem:

1.průchod - počítání slov

2.průchod - počítání znaků

3.průchod - kopírování slova vnořený ve 2., ať už pomocí memcpy nebo znak po znaku

Nahlásit jako SPAM
IP: 91.139.9.–
MilanL+1
Grafoman
3. 9. 2020   #16
-
0
-

Myslel jsem i na další varianty

spočítání znaků a slov, alokace pole na pointery a pole pro kopii věty, kopie věty s nahrazením delimiterů a uložením začátků slov do pole pointerů opět 3 průchody počítání/kopírování/náhrada delim s uložením pointerů

další 2 průchodový algoritmus byl se zásahem do původního 

1 průchodové varianty by se také našly ví o dvou
- alokovat pole pointerů a cílového řetězce určité velikosti a rovnou kopírovat, nahrazovat delimitery a ukládat pointery, při překročení kapacity pole pointerů nebo cíle realokovat na vyšší kapacitu

- struktura 2x char** první ukazuje na slovo, druhý na další strukturu  opět s alokací a realokací cílového řetězce

jako představit si to dokážu, ale jde občas o ty operace a pointery.

Nahlásit jako SPAM
IP: 91.139.9.–
Kit+15
Guru
3. 9. 2020   #17
-
0
-

#16 MilanL
Ty jednoprůchodové varianty máš správně. První používá např. Perl, druhou Lisp.

Nahlásit jako SPAM
IP: 46.135.12.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
MilanL+1
Grafoman
3. 9. 2020   #18
-
0
-

#17 Kit
no když by se ty alokace udělali dostatečně velké dalo by se i těm realokacím vyhnout případně hodně omezit jejich potřebu, např char** pro 100 slov a char* pro cíl třeba 128-1024

Nahlásit jako SPAM
IP: 185.112.167.–
Kit+15
Guru
3. 9. 2020   #19
-
0
-

#18 MilanL
Ano, tohle je také používané řešení, například u databází. Udělá se chunk vhodné velikosti a následně se uspořádají třeba do B-stromu. Je výhodné, pokud jsou všechny stejné velikosti, protožprotožprotože tak nedochnedochází k fragmentaci.

Nahlásit jako SPAM
IP: 213.175.43.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 26 hostů

Podobná vlákna

Pointer na char — založil _Radek_

Pointer na char array — založil oxidián

Pointer na pole struktur — založil Marcel

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý