| Autor | Správa |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: St 04.01.12 23:33 |   |
zdravim
mam tento program: | kód: | int main(void){
struct osoba{
char meno[20],priezvisko[20];
int vek;
};
int n;
puts("zadaj maximalny pocet poloziek");
scanf("%d", &n);
struct osoba pole[n];
int poradie=1,i=0;
while (i<n){
printf("zadaj meno %d osoby\n", poradie);
fgets(pole[i].meno, 19, stdin);
printf("zadaj priezvisko %d osoby\n", poradie);
fgets(pole[i].priezvisko, 19, stdin);
printf("zadaj vek %d osoby", poradie);
scanf("%d", &pole[i].vek);
i++;
poradie++;
}
printf("%s%s%d", pole[1].meno, pole[1].priezvisko, pole[1].vek);
return 0;
} |
nefunguje nacitanie do typu struktura cezprikaz fgets, akoby to na zadany udaj necakalo, help pls.
diki |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Št 05.01.12 12:29 |   |
Problem je v tom, ze na riadku:
Nacitavas len jeden udaj - cislo zo standardneho vstupu. Ty vsak napises cislo a stlacis enter. Ten enter ti ostava v bufferi na dalsie spracovanie. Ked sa dostanes na riadok:
| kód: | | fgets(pole[i].meno, 19, stdin); |
skontroloje sa buffer, ci tam uz nieco nie je. Ak ano, precita data z neho. To znamena, do pole[i].meno sa v tomto pripade ulozi spominany enter ( presnejsie povedane, znak noveho riadku ). To iste sa stane pri dalsom scanf, pri nacitani veku, opat v bufferi ostane novy riadok. Mozno sa pytas, preco sa nieco taketo nestane aj po volani funkcie fgets. Jednoducho preto, pretoze ta skopiruje vsetko az po nulovy znak ( koniec retazca ), pripadne maximalne 19 znakov a nulovy znak automaticky prida nakoniec sama. Cize precita sa aj spominany novy riadok - staci si vsimnut, ze ak napises napr meno "svejk", tak vyzva na napisanie priezviska je uz na dalsom riadku, pretoze sa precita "svejk[ENTER]".
Aby si tomu predisiel, staci po volani funkcie scanf vyprazdnit vstupny buffer. Napis si nasledujucu funkciu:
| kód: | void flush_stdin()
{
int c;
while ( ( c = getchar() ) != '\n' && c != EOF );
} |
ktoru jednoducho volaj po kazdom volani funkcie scanf:
| kód: | scanf( "%d", &n);
flush_stdin(); |
|
| |
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Št 05.01.12 13:14 |   |
nakoniec som to robil trochu pochopitelnejsie pre mna a sice touto funkciou: | kód: | void deleteEnter(char *string) {
char *znak = strrchr(string, '\n');
*znak = '\0'; |
no a zo scanf som to odstranoval pomocou
tomu s tym scanf nerozumiem (nasiel som to iba v jednom programe) ale vobec netusim jak to ze to robi to co chceme. co je to %*c??
diki |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Št 05.01.12 13:45 |   |
Ale ako chces pomocou tvojej funkcie deleteEnter zmazat vstup zo vstupneho buffra, ked ako argument davas retazec? Myslim, ze ti ta funkcia velmi nepomoze.
| svejk napísal: | | co je to %*c? |
"An optional starting asterisk indicates that the data is to be retrieved from stdin but ignored, i.e. it is not stored in the corresponding argument." - znamena to, ze sa precita dalsi znak ( iba jeden ) z buffra, ale neulozi sa do dalsej premennej, bude ignorovany.
Ak bude v buffri len znak noveho riadku, fajn, tento postup ti pomoze, ale co v pripade, ze tam bude este nieco? Opat dostanes chybny vstup. Teraz napisem dve verzie tvojho programu, len ho trocha skratim, aby tam nebol zbytocn cyklus. Spust si najprv prvy, potom druhy s tym, ze po vyzve "zadaj maximalny pocet poloziek", zadaj toto:
| citácia: | | 3 totojedlhypreklep |
Tvoja verzia s pouzitim scanf( "%*c" ) :
| kód: | #include <stdio.h>
int main(void){
struct osoba{
char meno[20],priezvisko[20];
int vek;
};
int n;
puts("zadaj maximalny pocet poloziek");
scanf( "%d%*c", &n );
struct osoba pole[n];
printf( "zadaj meno prvej osoby\n" );
fgets( pole[0].meno, 19, stdin );
printf( "zadaj priezvisko prvej osoby\n" );
fgets( pole[0].priezvisko, 19, stdin) ;
printf( "zadaj vek prvej osoby\n" );
scanf( "%d%*c", &pole[0].vek );
printf( "\n\nMeno = %s Priezvisko = %s Vek = %d\n", pole[0].meno, pole[0].priezvisko, pole[0].vek );
return 0;
} |
Moja verzia s vyprazdnenim celeho buffra :
| kód: | #include <stdio.h>
void flush_stdin()
{
int c;
while ( ( c = getchar() ) != '\n' && c != EOF );
}
int main(void){
struct osoba{
char meno[20],priezvisko[20];
int vek;
};
int n;
puts("zadaj maximalny pocet poloziek");
scanf( "%d", &n );
flush_stdin();
struct osoba pole[n];
printf( "zadaj meno prvej osoby\n" );
fgets( pole[0].meno, 19, stdin );
printf( "zadaj priezvisko prvej osoby\n" );
fgets( pole[0].priezvisko, 19, stdin) ;
printf( "zadaj vek prvej osoby\n" );
scanf( "%d", &pole[0].vek );
flush_stdin();
printf( "\n\nMeno = %s Priezvisko = %s Vek = %d\n", pole[0].meno, pole[0].priezvisko, pole[0].vek );
return 0;
} |
Vsimol si si rozdiel? V druhom pripade moze byt cokolvek v buffri, zmaze sa to vsetko. Ak vravis, ze to je pre teba tazkopadne pochopit, pokusim sa ti to vysvetlit, pretoze to ozaj nie je nic komplikovane. Je to iba jedna jednoducha slucka:
| kód: | | while ( ( c = getchar() ) != '\n' && c != EOF ); |
getchar() je funkcia, ktora nacita znak z buffra stdin. Znak sa ulozi do premennej c a nasledne sa kontroluje, ci sa nerovna '\n', co je znak noveho riadku, pripadne ci sa nerovna znaku EOF, co je signal, ze uz nie je co citat - to znamena buffer je prazdny. A kedze je to cele v podmienke while, bude sa citat cely buffer, pokial nenarazi na novy riadok, pripadne kym nedojde po koniec. To je cela veda. |
| |
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Št 05.01.12 14:10 |   |
a funkcia getchar automaticky aj vymaze ten hladany znak \n?
tu moju funkciu som pouzival po prikaze fgets... |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Št 05.01.12 14:26 |   |
Ano, vymaze, ale to spravi kazda funkcia, aj scanf napriklad. Ak sa nieco precita z buffra, automaticky to z neho aj odstrani. Ak si tu funkciu pouzival az potom, v poriadku. Sam sa rozhodni, aky postup budes pouzivat, ja som sa len snazil vysvtelit, co sa vlastne deje. Ak si tomu pochopil, uz si sam dokazes navrhnut riesenie. |
| |
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Št 05.01.12 23:23 |   |
|
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Ne 08.01.12 17:12 |   |
dobre, takze zapocet spraveny... teraz to potrebujem realnesie pochopit.
mali nasa uloha s casti spocivala v nacitani dat zo zuboru do strukturovanej premennej. Robil som to pomocou fgets. ten by mal kurzor vzdy aj premiestnit na dalsi riadok ci?
nacitaval som nasledovne:
| kód: | typedef struct info {
char dodavatel[20], mesto[20], produkt[20];
int cena, pocet;
}info;
info pole[10];
int main()
{
FILE *subor;
subor=fopen("data.txt", "r");
int ukon;
puts("1. pre info o dodavatelovi");
puts("2. pre info o produkte");
puts("3. pre najdenie najlacnejsieho skladu podla produktu");
puts("4. pre koniec");
scanf("%d", &ukon);
//nacita veci zo suboru do structury
for(int i=0; i<=7; i++){
fgets(pole[i].dodavatel, 19, subor);
fgets(pole[i].mesto, 19, subor);
fgets(pole[i].produkt, 19, subor);
fgets(pole[i].pocet, 19, subor);
fgets(pole[i].cena, 19, subor);
}
printf("%s", pole[0].cena); |
nakonci len pre kontrolu vypis nejakeho prvku. nevypisuje to tu hodnotu ktoru by som chcel..
subol vyzeral nasledovne:
Elektrosopa
Brno
telka
100
18000
Elektrosopa
Praha
telka
300
17300
KplusK
Brno
telka
430
19000
KplusK
Brno
dvd
430
1000
KplusK
Brno
pekarna
130
1489.45
KplusK
Ostrava
pekarna
120
1889.90
Najlacnejsi
Pardubice
pekarna
130
1429.60
moja myslienka bola najskor to vsetko nacitat do tej struktury a potom uz iba previest pozadovane operacie.. haldanie najnizsej ceny, vyhladanie skladu atd...
len pre info: data v subore su v tom poradi ako idu zasebou fkcie fgets teda.. dodavatel, mesto, produkt, pocet na sklade, cena...
program bol len na demonstraciu toho ci to vieme, v reale by mal zvladat aj keby tam bolo tych poloziek 1000
preco nefunguje teda dobre to nacitavanie?? asi tam je nejaky problem s polohou kurzoru..
diki |
| |
   |
 |
Fico
 Skúsený užívateľ
 Založený: 11.01.2009 Príspevky: 1052
 | Zaslal: Ne 08.01.12 17:41 |   |
Ked ti poviem, kde je problem, tak sa zasmejes
| kód: | fgets(pole[i].pocet, 19, subor);
fgets(pole[i].cena, 19, subor); |
| kód: | | printf("%s", pole[0].cena); |
S premennymi cena a pocet v strukture info pracujes ako s retazcom, kdezto v strukture su definovane ako int. Staci iba zmenit ich definiciu a vsetko pojde spravne:
| kód: | typedef struct info {
char dodavatel[20], mesto[20], produkt[20];
char cena[20], pocet[20];
} info; |
|
| |
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Ne 08.01.12 18:16 |   |
jeziiis, no tak tomu ver, vobec som si to neuvedomil... , mohol som mat o 5 bodou viac.. |
| |
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Pi 13.01.12 14:46 |   |
este jednu vec potrebujem...
nebudem davat cely kod.. je dlhy, dam iba cast ktora nefunguje, pritom by podlamna mala...
| kód: | case 3:
for(int d = 0; d<=7; d++){
pole[d].intcena = atoi(pole[d].cena);
pole[d].intpocet = atoi(pole[d].pocet);
//strcpy(pole[d].intcena, pole[d].cena);
//strcpy(pole[d].intpocet, pole[d].pocet);
}
puts("zadaj nazov produktu");
scanf("%s", &nazov1);
for (n=0; n<=7; n++){
if(strstr(pole[n].produkt, nazov1)!=NULL){
cena[indexc]=pole[n].intcena;
indexc++;
}
}
najlacnejsi=cena[0];
for(n=0; n<=9; n++){
if (cena[n]>najlacnejsi){
cena[n]=najlacnejsi;
}
}
printf("\nzadany produkt: %s ma najnizsiu cenu %dkc,-\n", nazov1, najlacnejsi);
} |
vypisuje to cenu, len nie najnizsiu, vypise to prvu co to najde..
poradte..
diki |
| |
   |
 |
nBXXL
 Užívateľ
 Založený: 27.12.2008 Príspevky: 978 Bydlisko: Nové Zámky, Slovensko Vek: 18
 | Zaslal: Pi 13.01.12 16:03 |   |
kontroluješ si vôbec čo píšeš?
úplne opačne máš ten if na konci..
keď už tak | kód: | {
if ( cena[n] < najlacnejsi ) najlacnejsi = cena[n];
} |
|
_________________ PC: MB: ASUS K8V SE Deluxe; CPU: AMD Athlon 64 2800+ 1.8GHz; GPU: Sapphire Radeon X1950GT AGP (500/600); RAM: Kingston 1GB DDR400 CL3 + A-Data 256MB DDR400 HDD: Western Digital 20 + 200GB; Monitor: LG 771E (17" CRT, stary ale dobry, aj ked trochu tmavy); PSU: Rexpower PZ-400W; OS: Windows 7 32-bit + ArchLinux 32-bit
NB: Asus K53SJ-SX093: i3-2310M + GT520M Optimus + 4GB RAM + Win7 64-bit + ArchLinux 64-bit | |
   |
 |
svejk
 Užívateľ
 Založený: 18.03.2007 Príspevky: 251
 | Zaslal: Pi 13.01.12 16:21 |   |
hej, to uz som si vsimol.. to som len zabudol zmenit ked som vselico s tym skusal..
naprava neriesi problem.. |
| |
   |
 |
nBXXL
 Užívateľ
 Založený: 27.12.2008 Príspevky: 978 Bydlisko: Nové Zámky, Slovensko Vek: 18
 | Zaslal: Pi 13.01.12 16:50 |   |
neviem ako to kompiluješ, ale problém by mohlo robiť to, že neinicializuješ indexc, ďalej, že pole cena[] je zbytočne veľké (prehľadávaš 9 prvkov, hoci viac ako 7 tam aj tak nenatrepeš, lebo tam hádžeš prvky zo 7-prvkového poľa pole[])..
po tej náprave to fungovať musí.. hľadáš najmenší prvok v poli či nie?
zopár rád:
- keď tie ceny môžu byť aj reálne čísla (demonštroval si to v príspevku vyššie), prečo používaš atoi?
- písal si, že v reále by mal zvládať aj 1000 položiek, no nepíšeš to takým spôsobom.. odporúčam ti dať si nejakú premennú, do ktorej uložíš počet položiek a potom v cykloch používať tú.. v prípade, že sa ti zmení počet položiek potom nemusíš prepisovať X cyklov |
_________________ PC: MB: ASUS K8V SE Deluxe; CPU: AMD Athlon 64 2800+ 1.8GHz; GPU: Sapphire Radeon X1950GT AGP (500/600); RAM: Kingston 1GB DDR400 CL3 + A-Data 256MB DDR400 HDD: Western Digital 20 + 200GB; Monitor: LG 771E (17" CRT, stary ale dobry, aj ked trochu tmavy); PSU: Rexpower PZ-400W; OS: Windows 7 32-bit + ArchLinux 32-bit
NB: Asus K53SJ-SX093: i3-2310M + GT520M Optimus + 4GB RAM + Win7 64-bit + ArchLinux 64-bit | |
   |
 |
|
Nemôžete pridávať nové témy do tohto fóra. Nemôžete odpovedať na témy v tomto fóre. Nemôžete upravovať svoje príspevky v tomto fóre. Nemôžete mazať svoje príspevky v tomto fóre. Nemôžete hlasovať v tomto fóre.
|
|