Portál AbcLinuxu, 1. června 2025 09:51


Dotaz: cyklus while a podivne spravanie

13.12.2005 19:55 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
cyklus while a podivne spravanie
Přečteno: 128×
Odpovědět | Admin
mam strasne neprijemny problem ktory ma brzdi pri zadani do skoly a preto hladam pomoc...neviem akym zazrakom ale ked tento program pustim a zadam 'b' tak mi do premennej pocet ulozi 1...avsak ked ten cyklus bezi dalej tak mne z neznameho dovodu premennu pocet vynuluje.. :(
#include malloc.h
#include stdio.h
#include stdlib.h
typedef struct {
  char meno[10];
  char priez[20];
  int oscislo;
  char znamka;
} STUD;

void vlozStud(int *pocet) {
  (*pocet)++;
}
  

int main() {
  
  int pocet;
  char vyber;
  
  pocet=0;
	
  STUD *student;
  student=(STUD *) malloc(1*sizeof(student));
  
 
  printf("%d\n",pocet);
  while (vyber!='x') { 
    scanf("%s",&vyber);
    if(vyber=='b') vlozStud(&pocet);
    printf("%d",pocet);
  }
  
  printf("%d",pocet);
  
  return (0);
}
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

13.12.2005 20:00 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Odpovědět | | Sbalit | Link | Blokovat | Admin
zabudol som ze pracujem v Anjute pod linuxami a najhorsie je ze pod win to ide :(
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
David Watzke avatar 13.12.2005 20:07 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Odpovědět | | Sbalit | Link | Blokovat | Admin
Nehodí kompilátor nějakej warning? Nepíšou se includy mezi < a >?
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
13.12.2005 20:09 zabza | skóre: 52 | blog: Nad_sklenkou_cerveneho
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
no to je jasný, jenže zkus si to zadat na ABCLinuxu s těma < a > ... :-)
13.12.2005 20:18 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
No a na co jsou asi nad polem pro zadávání příspěvku tlačítka '<' a '>'? Pro ty línější nabízím pomůcku, kterou jsem kdysi vyrobil kvůli starému redakčnímu systému Intervalu, ale hodí se i zde.
13.12.2005 20:21 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
hmm....ospravdlnujem sa to som si nevsimol ... :)
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
13.12.2005 20:08 zabza | skóre: 52 | blog: Nad_sklenkou_cerveneho
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Odpovědět | | Sbalit | Link | Blokovat | Admin
hint: kterým znakem končí v c-čku stringy?
13.12.2005 20:22 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
hmm...no nerozumiem resp. asi neviem na to vobec odpoved
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
13.12.2005 21:10 Martin Tůma | skóre: 39 | blog: RTFM | Praha
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie

Snažíš se zapsat řetězec na místo znaku. I když z klávesnice zadáš jenom "b", tak funkce scanf("%s", &vyber) na adresu &vyber uloží "b\0" (C-čkové řetězce jsou zakončeny znakem "\0"). A ten nulovej znak přepíše něco, co už nepatří k tomu charu. (V tvém případě proměnnou pocet)

To, že na windows to funguje je způsobený pravděpodobně "zarovnávánim" proměných v paměti, který provádí překladač - zapisuješ někam, kde by stejně nic nebylo.

Každý má právo na můj názor!
13.12.2005 20:14 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Odpovědět | | Sbalit | Link | Blokovat | Admin
  scanf("%s",&vyber);

Tak takové věci si raději hodně rychle odvykněte. Termín buffer overflow už jste slyšel? Tohle by byla sebevražda i kdyby proměnná vyber nebyla typu char.

13.12.2005 20:23 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
ok beriem a budem pamatat ale ako to ma byt spravne? resp. ako to riesit??
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
David Watzke avatar 13.12.2005 20:24 David Watzke | skóre: 74 | blog: Blog... | Praha
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Jak to má být správně? Takhle to je i v učebnici... no, v jiném spojení.
“Being honest may not get you a lot of friends but it’ll always get you the right ones” ―John Lennon
13.12.2005 20:27 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Máte pointer na proměnnou typu char a na místo, kam ukazuje, zkopírujete zadaný řetězec. Takže prvním znakem naplníte tu proměnnou a zbytkem přepíšete pár bytů za ním. Když budete mít štěstí, bude to pár jiných proměnných. Když ne, mohou se začít dít podivuhodné věci… V případě tazatele to zřejmě odnesla proměnná pocet, která se nacházela na zásobníku hned nad vyber.
13.12.2005 20:39 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
hmm...ok tak prosim ako to zapisat spravne? ale inak len tak mimo ze to pod win ide a to ma tiez hneva lebo pod win sa mi moc ten program pisat nechce...resp. nemam to cim prelozit a v com pisat...prosim dalo by sa navrhnut nejake riesenie konkretne presny zapis? inak ked tam dam namiesto scanf("%s",&vyber) scanf("%c",&vyber) tak mi to nevynuluje premennu pocet ale ten cyklus ide vzdy dvakrat namiesto toho aby si zakazdym vypytal zadat znak...
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
13.12.2005 20:48 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Asi byste si měl nejdřív zjistit, co vlastně děláte. Tedy nastudovat si z jakékoli učebnice jazyka C něco o tom, jaká je standardní reprezentace řetězců v jazyce C, co je to pointer a co dělá funkce scanf(). Bez toho to nepůjde a pokud si toto nastudujete, bude vám hned jasné, v čem je problém. Fórum vám může pomoci s konkrétním problémem, ale základy jazyka si musíte nastudovat sám.
13.12.2005 21:10 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
no mne je jasne to ze pod windowsackym compilerom to ide tak preto ma zaujima v com je problem....mne je jasne co je pointer aj co robi scanf ale ked mi nieco nejde tak skusam a vidim ze to pod win ide :(
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
13.12.2005 21:25 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Na začátku cyklu proměnná "vyber" není inicializována, takže je celkem náhoda, že to nějak funguje. Dále, "vyber" nesmí být "char", ale "pointer na char", tedy
char *vyber;
No a když je to takhle inicializováno, tak je potřeba paměť naalokovat
int N = 20;
vyber = (char *) malloc (N * sizeof(char));
a po použití uvolnit
free(vyber);
Přičemž NIKDY nepoužívej scanf() tak jak jsi to zapsal. Když už to mermomocí musíš napsat právě takto, tak aspoň
scanf ("%19s", vyber);
Abys omezil možnost buffer-overflow.
13.12.2005 22:05 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
ok dakujem velmi pekne skusim .....ale aj tak ma zaraza ze pod win to v poho funguje...a ze nie je inicializovana to som len zabudol moja chyba ale mam to tam.. :)
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."
13.12.2005 22:27 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
To, že to ve windows funguje, je opravdu náhoda. Každá platforma je trochu jiná. Céčko je trochu zrádné v tom, že špatně napsaný program někdy funguje, jindy zase ne, chová se "záhadně" v závislosti na ledasčem a dost špatně se hledají chyby.

Kdo s Céčkem teprve začíná, tak má dvojnásob složitou situaci. Jednak tápe, ale také používá "školské" ukázkové příklady, které jsou paměťově nenáročné a všechno se odehrává v zásobníku. Tam vznikají pravé záhady.

Zatímco když hrábneš někam daleko do paměti, která není tvoje, tak tě systém hned odstřelí a člověk hned ví, na čem je (teda někdy).

No nic, zkus tohle řešení:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>

typedef struct {
  char meno[10];
  char priez[20];
  int oscislo;
  char znamka;
} STUD;

void vlozStud(int *pocet) {
  (*pocet)++;
}


int main() {
  
  int pocet, N = 20;
  char *vyber;
  STUD *student;
  
  pocet=0;
	
  student=(STUD *) malloc(1*sizeof(student));
  vyber = (char *) malloc(N*sizeof(char));
 
  printf("%d\n",pocet);
  
  while(1){ 
    scanf("%19s", vyber);
    if (!strcmp(vyber, "x")) break;
    if (!strcmp(vyber, "b")) vlozStud(&pocet);
    printf("%d",pocet);
  }
  
  printf("%d",pocet);
  free(student);
  free(vyber);
  return (0);
}
(Chtěl jsem napsat ten program slušněji, ale to už bych ho příliš měnil.)
14.12.2005 08:27 Martin
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Tak zkuste ten svůj původní program spustit pod windows a místo jednoho písmenka jich zadejte najednou třeba dvacet a vsadil bych se že ten program spadne i pod windows, protože si něco přepíšete.

Nebo zkuste mezi
int pocet;
char vyber;

vložit nějakou proměnou, kterou dále v programu nijak nepoužijete (doufám, že ji kompilátor bez optimalizace nevyhodí, pokud ano, tak ji nějak nesmyslně použijte, aby zůstala v tom programu zachována). A spusťte program pod linuxem a zadejte jedno písmenko a program najednou bude chodit v pořádku.

14.12.2005 11:59 oxymoron | skóre: 16 | blog: oxymoron | Bratislava
Rozbalit Rozbalit vše Re: cyklus while a podivne spravanie
Dakujem vsetkym velmi pekne za odpovede :)
Born to be root ... :-D | "..žebrák není ten, kto svobodu si získal, z toho se stává král.."

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.