Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: premet 25 Listopadu 2008, 17:06:26
-
Zdravím,
Když už tady je to téma s tím programováním tak by mě zajímalo tohle, protože jinde nemám kde koho otravovat. Mám úkol v Cčku napsat funkci, která vrátí počet výskytů podřetězce (slova) v řetězci. Nejsem s prácí s řetězci ješte tak sběhlej a na ten úkol mám ješte dost času, ale nešel mi net tak sem neměl co dělat :).
Úkol : #include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*funkcni prototypy*/
int pocet_vyskytu(char *p_vyskyt, char *p_retezec);
int main(void) {
int i, delka_vys, delka_ret;
char *retezec, *vyskyt;
retezec = (char *) malloc(101 * (sizeof(char)));
vyskyt = (char *) malloc(31 * (sizeof(char)));
printf ("Zadejte řetězec maximální délky 100 znaků: \n");
fgets (retezec, 101, stdin);
/*while (getchar() != '\n')
;
*/
delka_ret = strlen(retezec);
if (retezec[delka_ret-1] == '\n') {
retezec[delka_ret-1] = '\0';
}
printf ("Zadejte hledaný řetezec: \n");
fgets (vyskyt, 31, stdin);
delka_vys = strlen(vyskyt);
if (vyskyt[delka_vys-1] == '\n') {
vyskyt[delka_vys-1] = '\0';
}
i = pocet_vyskytu(vyskyt, retezec);
printf ("Počet výskytů řetězce %s je %d.\n", vyskyt, i);
}
int pocet_vyskytu(char *p_vyskyt, char *p_retezec) {
int pocet = 0;
char *p_c;
p_c = (char *) malloc(100 * (sizeof(char)));
while ((p_c = strstr(p_retezec, p_vyskyt)) != NULL) {
pocet++;
p_retezec = ++p_c;
}
return pocet;
}
a problém je v tom, že když zadám příliš dlouhou větu tak to zůstane v bufferu a automaticky se to použije ten zbytek i jako vyhledávaný řetězec a mě by zajímalo jestli tam lze dát nějakou podmínku na začátku jak mám zakomentovaný to while na vyprázdnění bufferu, že se to použije jen tehdy, když je to delší než má.
Ukázka : Zadejte řetězec maximální délky 100 znaků:
Pejsek s kocickou si koupily novej dum. Bydleli tam asi pul roku a pak si pejsek nasel jinou kocicku. Kocicka z toho byla nestatstna a sla pejska zabit, protoze to byl peknej zmetek. Zili bez sebe stastne az do smrti.
Zadejte hledaný řetezec:
Počet výskytů řetězce . Kocicka z toho byla nestatst je 0.
jinak to funguje :).
PS: Kod není určitě dokonalej a určitě se tam najde spousta blbých a zbytečných věcí ;). Začínám no :-\
-
No jestli jsem to pochopil, tak pokud je řetězec větší než 100 nevejde se to samozřejmě do proměnný.
Todle:
delka_ret = strlen(retezec);
if (retezec[delka_ret-1] == '\n') {
retezec[delka_ret-1] = '\0';
}
bych nahradil:
delka_ret = strlen(retezec);
if (delka_ret > 100)
retezec[100] = '\0';
ted mě napadá, jestli strlen vrátí vůbec někdy více jak 100.
Btw fgets? To se používá u souboru ne? Možná bych zkusil scanf ;)
-
.. protože jinde nemám kde koho otravovat...
?IRC neznas..
-
Nemůže tam být scanf, protože ten to načítá až po první bílej znak, takže když budou mezi slovy mezery tak to načte jen to první. Zkoušel sem ten způsob, ale takhle to nejde. Budu muset nad tím ješte koumat jak to vylepšit :).
.. protože jinde nemám kde koho otravovat...
?IRC neznas..
Znám IRC, ale nikdy sem tam nechodil, jenom jednou na spolužácký a zkoušel sem se akorát podívat na nějaký Linuxový, ale to bylo na začátku školního roku a pak už ne. Tohle mě vůbec nenapadlo :).
-
Jo jasně máš pravdu.... spíš teda jen gets ;) namísto fgets.
Hmm to je potvora... jsem si to myslel, že strlen vrátí max 100 a víc ne... a co tam dát rovnou:
retezec[100] = '\0';
-
Podle mojí moudré knihy ;D "učebnice jazyka C" se nedoporučuje používat gets, protože nehlídá přetečení řetězce, kdežto u fgets to je přímo parametr. Ono se dá použít to while (getchar() != '\n', ale pokud ten řetězec není delší tak to musím navíc od-enterovat. Dát tam ukončovací nulu nepomůže, protože ten zbytek co to odkrojí za tou stovkou jde dál.
-
Jako nemusím to mít za každou cenu, prostě mu to dám tak :). Ale děkuji za snahu :-* ;D.
-
alokovat delsi retezec by nepomohlo? nebo rozdelit tu dlouhou vetu do nekolika retezcu a ty pak zkontrolovat?
-
No alokovat více paměti je samozřejmě možný... ale pokus se zase překročí ten max, tak to zase bude dělat to co to dělá.
Co takhle alokovat takhle:
char * l_retezec = new char[];
-
Tohle jsem teda nějak nepochopil ??? . Můžu poprosit o trochu bližšího vysvětlení ?.
-
pokial viem, new a delete je vec c++ a nie c..
myslim ze by ti stacilo dat pole o 1000 znakov, dlhsie vety asi pisat nebudes ze ?
-
No vidíš, tohle mě vůbec nenapadlo :D. Sem si říkal, že mi to new char[] nic neříká :). Tak já to udělám takhle a už na to kašlu abych se s tím trápil, když je to jen za 2 body. Tak dík chlapi
-
Kruci... je pravda, že mě netrápí C/C++ a ty to chceš jen v C. Tadle kombinace je dobrá nebot by měla dynamicky zvětšovat to pole.
Až mě to na... tak to hodím do visualu :D
Jináč není zač.... rád pomohu... C/C++ je koníček ;)
-
Jo mě taky to C jaksi chytlo, možná až se naučím dobře C tak se vrhnu na C++ uvidíme, času je dost :). Kdybych nemusel strávit víc času nad učením se jazyka Scheme tak bych si nemusel knížku o C číst jen v buse ;D.
-
Poslal jsem úkol, ale prej máme zakázáno použít jakékoliv knihovny jako string.h nebo stdlib.h takže sem to musel udělat bez toho. Vypadá, že mi to funguje už
EDIT: Tak učitelovi tam zase něco nefungovalo tak koho zajímá, dal jsem sem již opravenou verzi, která mi snad již funguje ;D.
EDIT2: Stejně tam našel něco blbě tak jsem to udělal ješte jinak :D.
#include <stdio.h>
/*funkcni prototypy*/
int pocet_vyskytu(char *p_vyskyt, char *p_retezec) ;
int main(void) {
int i, j;
char retezec[1000];
char vyskyt[30];
printf ("Zadejte řetězec maximální délky 1000 znaků: \n");
fgets (retezec, 1000, stdin);
printf ("Zadejte hledaný řetezec: \n");
fgets (vyskyt, 30, stdin);
for (j = 0; j < 30; j++) {
if (vyskyt[j] == '\n') {
vyskyt[j] = '\0';
}
}
i = pocet_vyskytu(vyskyt, retezec);
printf ("Počet výskytů řetězce %s je %d.\n", vyskyt, i);
}
int pocet_vyskytu(char *p_vyskyt, char *p_retezec) {
int pocet = 0;
int i = 0;
int j, k = 0;
for (j = 0; j < 1000; j++) {
if (p_vyskyt[i] == p_retezec[j]) {
i++;
if (p_vyskyt[i] == '\0') {
pocet++;
i = 0;
for (k = 0; k < 30; k++) {
if (p_vyskyt[k] == '\0') {
break;
}
}
if (k > 1) {
j = j - (k - 1);
}
}
}
if (p_retezec[j] == '\0') {
break;
}
}
return pocet;
}
-
To jo potvora ten učitel :D
Jj hezký... nechce se mi to dávat do VS, tak se zeptám... teď když je to staticky alokováno, tak pokud je retezec větší jak 1000, tak už se to chová normálně?
-
Nene, stále pokud dám řetězec delší než těch 1000 znaků tak to dělá to co předtím, ale jakože "nepředpokládám", že by někdo dal delší tak sem to neřešil ;D. Stejně tam mám blbě ješte jednu věci tak se na to musím ješte mrknout :).
-
Tak mi to nedalo a zalistoval jsem trochu v msdn a použil debug v MS Visual Studiu a ejhle... našel jsem ti řešení:
printf ("Zadejte hledaný řetezec: \n");
flushall();
fgets (vyskyt, 30, stdin);
Zjistil jsem, že v nějakým globálním bufferu zůstane ten ořízlej zbytek a ten se pak automaticky hodí jako vyhledávaný řetězec. No tak jsem hledal jak ten buffer vynulovat a našel jsem funkci flushall ;)
Takže teď pokud zadáš něco větší jak 1000 znaků, tak se to prostě samo ořízne a veme se jen max 1000 znaků.
-
Bohužel takhle se ta funkce použít nedá :-[. Co jsem se díval tak to funguje taklhe
#include <stdio.h>
int main( void )
{
int numflushed;
numflushed = _flushall();
printf( "There were %d streams flushed\n", numflushed );
}
a to mi bohužel nepomůže. Však mu nejde o tohle, ale hlavně aby fungovala ta funkce pocet_vyskytu :).
-
? já to mám vyzkoušený a pomohlo to ;) vymazalo to buffer co si to pamatovalo z minulýho vstupu.
Jo to jsem si všimnul, že ta funkce to špatně počítá, ale tu jsem neopravoval to nechám na tobě :P
-
Mě to hodilo chybu při kompilaci, tak jdu na matiku a vyzkouším pozdějí tak díky :).
-
No ještě jsem se pro jistotu koukal a tato funkce je dostupná z hlavičkového souboru stdio.h a ta se na poslední tebou daném výpisu zde objevuje, tak nevidím problém ;)
-
To je divný ???
prema@debian:ukoly_skola$ gcc -o navic_uloha navic_uloha.c
/tmp/ccwNFrfr.o: In function `main':
navic_uloha.c:(.text+0x4c): undefined reference to `flushall'
collect2: ld returned 1 exit status
-
zkus to takto: _flushall();
-
To jsem taky zkoušel a udělá to to samí. Je to divný no :).
-
Co fflush? (někde jsem četl, že by to měl být ekvivalent)
-
Zkoušel sem fflush(stdin), ale nefunguje to :). Už to nechám být, koukal sem se a Bufferování mám v mojí moudré knize ve druhém dílu tak za chvilku dočtu první tak se vrhnu na druhý.
Jinak už úloha je uplně funkční (viz. níže) a dostal sem za ni 2 body ;D.
Dík moc za pomoc a když budu cokoliv potřebovat aspoň vím za kým se tu obrátit :).
-
Zkoušel sem fflush(stdin), ale nefunguje to :). Už to nechám být, koukal sem se a Bufferování mám v mojí moudré knize ve druhém dílu tak za chvilku dočtu první tak se vrhnu na druhý.
Jinak už úloha je uplně funkční (viz. níže) a dostal sem za ni 2 body ;D.
Dík moc za pomoc a když budu cokoliv potřebovat aspoň vím za kým se tu obrátit :).
Hmm zajmavý... každopádně pod woknama to funguje jak jsem psal ;) V linuxu jsem to nezkoušel ;) a nemáš zač... jj myslíš asi na mě co ;D
-
Jo padl jsi mi do oka :-* ;D ;D.