Obousměrný seznam v C – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Obousměrný seznam v C – C / C++ – Fórum – Programujte.comObousměrný seznam v C – C / C++ – Fórum – Programujte.com

 

Milan980
Newbie
2. 1. 2009   #1
-
0
-

Chtěl bych požádat nějakou dobrou duši o pomoc. Do školy mám vypracovat program jehož hlavní součástí je seznam s možností přidávání na konec i začátek s použitím pointerů. Přidání na konec funguje, ale s přidáním na začátek mám problém (vím, že tam má být pointer na předchůdce). poraďte pls (nejradši přímo dopsáním :)



typedef struct osoba{
char jmeno[30];
int vek;
struct osoba *dalsi; ///pointer na dalsi strukturu
} OSOBA;

OSOBA *alokuj() ///vraci pointer na alokovanou pamet struktury osoba
{
OSOBA *os;
os=(OSOBA*)malloc(sizeof(OSOBA));
return os;
}

void nacti(OSOBA *os ) ///neni nutna navratova hodnota
{
printf("Zadejte jmeno:");
scanf("%s", os->jmeno);
printf("Zadejte vek:");
scanf("%d", &os->vek);
os->dalsi=NULL; ///nastaveni pointeru na dalsi strukturu na "zakladni" hodnotu
}

int main(int argc, char* argv[])
{
OSOBA *osoba,*nulta, *prvni, *aktualni,*posledni, *pomocna,*pomocna2,*nej;
int i;

osoba=alokuj();
nacti(osoba);
prvni=osoba; ///zapamatovani prvni polozky seznamu
posledni=osoba; //ulozeni pointeru posledni zpracovane polozky seznamu

osoba=alokuj();
nacti(osoba);
posledni->dalsi=osoba; ///nastaveni pointeru z minule struktury na aktualni
posledni=osoba; ///ulozeni pointeru posledni zpracovane polozky seznamu


printf("\n");
pomocna=prvni;

while(pomocna!=NULL) ///dokud neni pointer NULL => je NULL u posledni polozky seznamu
{
printf("%s - %d\n", pomocna->jmeno, pomocna->vek);
pomocna=pomocna->dalsi; ///prejiti na dalsi polozku v seznamu
}
pomocna=prvni;
int nejstarsi=0;

while(pomocna!=NULL)
{if(pomocna->vek > nejstarsi) {nejstarsi=pomocna->vek;nej=pomocna;
}
pomocna=pomocna->dalsi;}

printf("%s - %d\n", nej->jmeno, nej->vek);

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
2. 1. 2009   #2
-
0
-

To máš velmi jednoduchou modifikací

OSOBA* nazacatek(OSOBA* minprvni){
OSOBA *osoba;
osoba=alokuj();
nacti(osoba);
osoba->dalsi=minprvni;
return osoba;
}

zavoláš vždy v main:
prvni=nazacatek(prvni);

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
2. 1. 2009   #3
-
0
-

To o-lox : Opravdu moc děkuji. Ještě bych potřeboval, aby program dokázal uložit seznamy do binárního souboru a zase je z něj načíst. Byl bych fakt vděčnej. Už to zas zkouším hrozně dlouho a nefunguje a nefunguje. Zkusil jsem si práci s bin souborama u polí, což chodilo v pohodě, ale u seznamu jsem ztracen. Jsem prostě programátorsky neschopnej....... :smile10:

Nahlásit jako SPAM
IP: 88.103.50.–
KIIV
~ Moderátor
+43
God of flame
2. 1. 2009   #4
-
0
-

To Milan98 : muzes ukladat celou strukturu... akorat si pak nezapomen predelat ty ukazatele... kdyz bys to nacetl tak jak to lezi-bezi tak ty adresy uz nejspis nebudou spravne-...

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Milan980
Newbie
2. 1. 2009   #5
-
0
-

Hmm. Je mi jasné, že takovéto problémy tam asi budou. Potřeboval bych asi spíše kodové vyjádření, než slovní radu...

Nahlásit jako SPAM
IP: 88.103.50.–
Jura
~ Anonymní uživatel
637 příspěvků
2. 1. 2009   #6
-
0
-

V žádném případě NEukládej strukturu jako celek. Zaděláš si s tím akorát na problémy. Jednak je zbytečné ukládat honoty ukazatelů a za druhé, struktury se obvykle nějakým způsobem zarovnávaji, tzn že sizeof(struktura) se nemusi nutně rovnat součtu velikostí položek struktury.

Nahlásit jako SPAM
IP: 85.207.192.–
KIIV
~ Moderátor
+43
God of flame
2. 1. 2009   #7
-
0
-

Milan98 napsal:
Hmm. Je mi jasné, že takovéto problémy tam asi budou. Potřeboval bych asi spíše kodové vyjádření, než slovní radu...


k cemu by to pak bylo... vsichni maj radsi kdyz za ne to co maj udelat udela nekdo jinej.. nez by zapli mozek...

Nahlásit jako SPAM
IP: 77.237.136.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Milan980
Newbie
2. 1. 2009   #8
-
0
-

To KIIV : no asi takhle. Jsem v tom celkem začátečník. Není to rozhodně o tom, že bych byl línej, nechtěl přemýšlet, nechtěl tomu věnovat čas atd. atd. Ono když se problémem zabývám nějakou tu hodinu a stále bez pokroku, tak je to celkem těžký. Když nevím jak se v základu ta struktura dá uložit, tak se asi moc nehnu.... Hledal jsem všude možně a nikde jsem žádný příklad o ukládání seznamu do bin souboru nenašel...... Když ti vadí má prosba o pomoc, tak mi neraď, ale tohle si opravdu nech....

Nahlásit jako SPAM
IP: 88.103.50.–
crAzY^
~ Moderátor
+10
Grafoman
2. 1. 2009   #9
-
0
-

To Milan98 : on má pravdu, už to tu bylo milionkrát, že někdo chce aby za něj něco udělal někdo jiný, ale takhle to nefunguje...

Nahlásit jako SPAM
IP: 89.190.64.–
All you need is vision and time.
Jura
~ Anonymní uživatel
637 příspěvků
2. 1. 2009   #10
-
0
-

To Milan98 :

Malý přiklad jak uložit nějaké hodnoty do bin souboru. Není to nic světoborného - jedná se pouze o jednoduchou (de)serializaci, kde položky jsou rozlišeny jen polohou v souboru(nemají žádne jméno, atd), ale to bz ti přesto mělo stačit. Podobně to uděláš u těch struktur - nějakou funkci, která uloží/načte jednu strukturu (jednotlivé položky), pak dalsi funkci, která načte/uloží celý seznam, atd..

zde je kod testovací aplikace - je to jen test tak nekontroloju všechny návratové hodnoty.



#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <string.h>
#include "serializace.h"

#define MAX_TEXT 256

int main()
{
int iValue = 100, iValue2 = 0;
double dValue = 1.5, dValue2 = 0.0;
char szText[MAX_TEXT] = {0}, szText2[MAX_TEXT] = {0};

/*otevru pro zapis v bin. rezimu*/
FILE * pFile = fopen("test", "wb");
if( pFile )
{
strcpy(szText, "Tak co tu máme?");
/* Samozrejme bys mel testovat navratove hodnoty */
SaveIntToBinFile(pFile, iValue);
SaveDoubleToBinFile(pFile, dValue);
SaveStringToBinFile(pFile, szText);

fclose(pFile);
}
/* otevru pro cteni v bin rezimu */
pFile = fopen("test", "rb");
if( pFile )
{
LoadIntFromBinFile(pFile, &iValue2);
LoadDoubleFromBinFile(pFile, &dValue2);
LoadStringFromBinFile(pFile, szText2, MAX_TEXT);

/*overeni*/
assert( iValue == iValue2 && "Integer se nepovedlo nacist" );
assert( fabs(dValue - dValue2) < DBL_EPSILON && "Nepoveldo se nacist double" );
assert( 0 == strcmp(szText, szText2) && "Text se nepovedlo nacist" );

fclose(pFile);
}

return 0;
}


Nahlásit jako SPAM
IP: 85.207.192.–
Milan980
Newbie
2. 1. 2009   #11
-
0
-

To crAzY^ : jj chápu, jen nemám rád když ze mě někdo dělá nějakýho lenocha......

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
2. 1. 2009   #12
-
0
-

Teda tady jsem se zase ve vlákně pobavil :D

	osoba=alokuj();

prvni=osoba;
while (1)
{
read(soub,&osoba->jmeno,sizeof(char[30]));
read(soub,&osoba->vek,sizeof(int));
if (eof(soub)) break;
osoba->dalsi=alokuj();
osoba=osoba->dalsi;
osoba->dalsi=NULL;
}


na načtení , když jsi dobrý v souborech zvládneš zápis i další úpravy...

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
2. 1. 2009   #13
-
0
-

díky všem za rady. Jdu se snažit to nějak zvládnout :smile1:

Nahlásit jako SPAM
IP: 88.103.50.–
Milan980
Newbie
3. 1. 2009   #14
-
0
-

tak jsem opět tu. Zkoušel jsem tedy udělat ten zápis do souboru a znovu načíst. funguje to, ale neúplně. Prosil bych tedy o nalezení chyb. Hned sám mohu říct, že mám špatně zvolený cyklus pro načtení, ale to není asi kámen úrazu.
uložení:

	FILE *f;

f=fopen("data.dat","wb");
while(pomocna!=NULL)
{fwrite(pomocna,sizeof(osoba),1,f);
pomocna=pomocna->dalsi;}
fclose(f);


načtení:
f=fopen("data.dat","rb");

osoba=alokuj();
read(f,&osoba->jmeno,sizeof(char[30]));
read(f,&osoba->vek,sizeof(int));
prvni=osoba;
posledni=osoba;
osoba->dalsi=NULL;
for(i=0;i<2;i++){
osoba=alokuj();
read(f,osoba->jmeno,sizeof(char[30]));
read(f,osoba->vek,sizeof(int));
posledni->dalsi=osoba;
posledni=osoba;
osoba->dalsi=NULL;}
fclose(f);

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
3. 1. 2009   #15
-
0
-

Ty neumíš ale vůbec pracovat se souborama je mi líto. Povídal jsi pohádky

Zkusil jsem si práci s bin souborama u polí, ...


jak potom můžeš montovat dohromady zhola odlišné přístupy práce se souborem, FILE* a HANDLE ?
Pro načtení prosimtě okopíruj přesně to moje a na otevření souboru dej open("data.dat",O_BINARY+S_IREAD);
NA ULOZENI udelej presny opak kdyz nacitas polozky postupne tak je tak i ukladej misto read bude v cyklu write.

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
3. 1. 2009   #16
-
0
-

To o-lox : Netvrdil jsem, že se souborama umím nějak extra pracovat. Jen, že jsem si to zkusil u pole a tam mi to uložilo i zpět načetlo v pohodě. dík za rady. jdu to zas předělat....

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
3. 1. 2009   #17
-
0
-

To Milan98 : jsem skolen streptokokem, rád na tobě posekám dříví ... :D

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
3. 1. 2009   #18
-
0
-

To o-lox : jak mám prosímtě deklarovat "soub" ? Jsem z toho jelen (bude to asi tím, že jsem ani nevěděl, že je ještě jiný typ přístupu než FILE*. Pročítám pořád různý příručky, ale na tohle jsem ještě nikde nenarazil......

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
3. 1. 2009   #19
-
0
-

int soub;

_fmode=O_BINARY;
soub=creat("data.dat",S_IWRITE);
...
close(soub);

EDIT: hlavicky:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
jestli ti nejde creat dej _creat
nebo i soub = _open( "data.dat", _O_WRONLY | _O_CREAT, _S_IREAD | _S_IWRITE );

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
3. 1. 2009   #20
-
0
-

To o-lox : jj dík. Na hlavičky jsem přišel a creat take funguje. Už mi to načte a vypíše, ale jen jednu položku. Zkusím si s tím trochu pohrát.

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
3. 1. 2009   #21
-
0
-

To vypadá jako bys nechal v ukládání třeba podmínku eof(soub) -- break;

Při ukládání musíš mít podmínku na while(osoba=osoba->dalsi); // dole v cyklu do {..} while();

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
3. 1. 2009   #22
-
0
-

To o-lox : to jsem měl smazané. Je tam asi ten problém, že ukazatel neukáže na další položku která se má načítat. V ukazatelích se taky ztrácím (vždycky jsem je ve škole obcházel, a teď mi bohužel dali do zadání: musí být tvořeno s použitím ukazatelů :( jednou to stejně muselo přijít).

Nahlásit jako SPAM
IP: 88.103.50.–
o-lox0
Super člen
3. 1. 2009   #23
-
0
-

 soub=creat(..);

osoba=prvni;
while(osoba!=NULL)
{
write(soub,&osoba->jmeno,sizeof(char[30]));
write(soub,&osoba->vek,sizeof(int));
osoba=osoba->dalsi;
}
close(soub);

Pouzil jsem tento zapis a presne svuj kod pro cteni a funguje to.
pro cteni parametr READ:
soub = open( "OPEN.OUT", _O_RDONLY | _O_CREAT, _S_IREAD | _S_IWRITE );

Nahlásit jako SPAM
IP: 85.71.152.–
Milan980
Newbie
3. 1. 2009   #24
-
0
-

To o-lox : Měl jsem chybu v podmínce. Tímto fakt děkuju. Především za ty binární soubory, které bych fakt nezvládl...... Mám se co učit no...

Nahlásit jako SPAM
IP: 88.103.50.–
Jarmik
~ Anonymní uživatel
2 příspěvky
3. 1. 2009   #25
-
0
-

Ahoj, měl by sem malou prosbu, pročetl jsem si celé vlákno a před tím než zkusím to co jste doporučili Milanovi, by sem se chtěl zeptat, zda nevíte jaká by v tomto segmentu kodu mohla být chyba. Načital sem nejprve přes nekončený cyklus a to fungovalo, ale raději by sem použil while cyklus s touto podmínkou. Chyba je v tom, že při čtení ze souboru mi VS zahlasí že "nova" neni inicializováno a pak přistpuji k pamětí která mi nepatři a to právě nechápu. Díky moc za jakýkoliv tip

int Nacti(AUTOMOBIL **prvni, AUTOMOBIL **posledni)

{
FILE *f;
AUTOMOBIL *nova, *pomocny=NULL;
int zacatek=1;
char nazevSouboru[10];

printf("Zadejte nazev souboru:");
scanf("%s", nazevSouboru);

if(!(f=fopen(nazevSouboru, "rb"))) return 0;

while(fread(nova,sizeof(AUTOMOBIL),1,f), feof != 0)
{
if(zacatek)
{
nova=init();
*prvni=nova;
prvni=0;
}
else
nova->predchozi=pomocny;
pomocny=nova;
nova=init();
pomocny->dalsi=nova;
}
*posledni=pomocny;
free(nova);
(*posledni)->dalsi=NULL;
return 1;
}

Nahlásit jako SPAM
IP: 77.48.18.–
MaS0
Návštěvník
4. 1. 2009   #26
-
0
-

To Jarmik : ten přístup k paměti by mohl být tím, že pole nazevSouboru není ukončeno (znak '\0') a proto funkce fopen jde až do paměti, která není tvoje.....a to, že je *nova neinicializovaný, je proto, že je to ukazatel a neukazuje na žádnou paměť (musí mu být přiřazena pomocí new/malloc).....nějaký další věci, který by se možná měli opravit:
1. proměnná zacatek je pořád nastavená na 1, takže tam na to else nikdy nedojde
2. to asi špatně chápu...proč načítáš ze souboru do paměti AUTOMOBIL, když mu pak hned stejně přiřadíš jinou hodnotu??

Nahlásit jako SPAM
IP: 195.146.114.–
o-lox0
Super člen
4. 1. 2009   #27
-
0
-

To MaS : ten nazevsouboru se ukonci sam tou funkci scanf, jinak s tebou souhlasiim, doplnil bych snad ze tam ma nesmysl i u
feof !=0
to tam byt nema staci v podmince to fread.
Je to tak trosku cely kandidat na celopredelani.

Nahlásit jako SPAM
IP: 85.71.152.–
Jarmik
~ Anonymní uživatel
2 příspěvky
4. 1. 2009   #28
-
0
-

celopředělání už bylo provedeno a funguje to konečně jak má.. Měl sem tam ještě nejasnosti, které si stačilo urovnat a už to šlo udělat, díky za tipy.

Nahlásit jako SPAM
IP: 77.48.18.–
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, 10 hostů

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ý