Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: c tietueet

Sivun loppuun

timok16 [03.02.2005 16:47:48]

#

moikka,
Kuinka voidaan tietueiden funktioiden kanssa keskustella?
Tarkoitan sitä että pitäisi pystyä käyttämään Asiakas-tietueessa Tilaus-tietueen funktiota TilausValikko().
Kiukkuu mulle tälläistä virhettä kokoajan:
unresolved external symbol "public: void __thiscall TILAUS::TilausValikko(void)" (?TilausValikko@TILAUS@@QAEXXZ)
Tarkoitus päästä asikakkaan poiston jälkeen poistamaan myös tilaus.
ohjelmani rakenne:
main()--->päävalikko
Asiakas--->tietue--->asiakas.cpp
Tilaus--->tietue--->tilaus.cpp
eli jos ymmärrätte, niin viite-eheys olis tässä tarkoituksena.

timok16 [03.02.2005 19:10:10]

#

struct ASIAKAS {----->tämä ihan omana headerinä

char address[21];
char postcode[6];
char city[21];
char asnimi[31];
char astunnus[7];

};



#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>
#include "TILAUS.H"
#include "ASIAKAS.H"

TILAUS tietue;// /*tässä tehty TILAUS-tyyppinen tietue-muuttuja*/
struct ASIAKAS asiakas;
FILE *fileptr;

/****tässä paljon muitakin funktioita********/

void delete_asnimi()
{
strcpy(asiakas.astunnus, " " );
fwrite(&asiakas, sizeof(asiakas), 1, fileptr);

//tietue.TilausValikko();
/***********kuinka saadaan toisen tietueen funktiot käyttöön***********/
/*tarkoitus päästä Tilaus-tietueen TilausValikko()-funktioon ja
sieltä valikosta valita PoistaTilaus()-funktio.*/
}

WinC [03.02.2005 23:22:50]

#

turpo16 kirjoitti:

Kuinka voidaan tietueiden funktioiden kanssa keskustella?
Tarkoitan sitä että pitäisi pystyä käyttämään Asiakas-tietueessa Tilaus-tietueen funktiota

Tietueille ei voi tehdä omia siäisiä funktioita, mutta luokille voi.

funktiomäärittely

Tilaus::TilausValikko(void)

kertoo, että TilausValikko() funktio kuuluu luokalle nimeltä Tilaus. Tällaisia funktiomäärittelyjä et voi tehdä structeille. Kyseisen luokan Toteutus voisi olla seuraavan lainen.

class Tilaus {
public:
    void TilausValikko(void); //määritellään julkinen metodi
};

Tilaus::TilausValikko(void)
{
//...funktion toteutus
}

Kannatan tutustumista luokkiin ja c/c++ kielen perustietorakenteisiin. Esimerkiksi jonkin oppaan avustuksella, joita varmasti netistä löytyy riittämiin.

rutkis [04.02.2005 10:12:26]

#

C++:ssa tietueeseen voidaan kirjoittaa alkioiden attribuuttien lisäksi jäsenfunktioita.

struct cPiste {
 int x,y;
 void tulosta() const;
};

void cPiste::tulosta() const
{
printf("(%d,%d)\n",x,y);
}

Structeihin voi laittaa funktioita yms, mutta ne näkyvät muille public-tyyppisiä. Private/Protected on luokkien ominaisuuksia.

timok16 [04.02.2005 13:09:53]

#

void delete_asnimi()
{
strcpy(asiakas.astunnus, "      " );
fwrite(&asiakas, sizeof(asiakas), 1, fileptr);


tietue.TilausValikko(); //ei noteeraa koko lausetta
cout<<"meneeko tanne "<<endl;//tää kyllä tulostuu


}
int get_choice()

{
	int c=0;
	printf("\n\n ------ MENU ------ \n\n");
	printf("Valitse ja paina Enter\n\n");
	printf(" 1. Lisaa asiakas\n");
	printf(" 2. Etsi asiakas\n");
	printf(" 3. Nayta kaikki asiakkaat \n");
	printf(" 4. Paivita asiakkaan tietoja\n");
	printf(" 5. Poista asiakas\n");
	printf(" 0. Lopeta\n\n");
	printf(" Valinta > ");
	scanf(" %d", &c);
	return c;
}
[c/koodi]
/*ekana ollaan ASIAKAS-tietueessa ja sieltä kun poistetaan asiakas, pitäisi päästä TILAUS-tietueen TilausValikko()-metodiin, jonka kautta voidaan taas poistaa
kyseisen asiakkaan tilaus.*/
/*ajatuksena tehdä niinkuin c++:ssa onnistuu eli koostaminen*/
/*main():sta onnistuu pomppiminen mitenpäin vain,
mulla main()-funktiossa vain päävalikko*/

dungeon86 [04.02.2005 13:41:14]

#

Vaihda homma kokonaan C-kieleen, paljon helpompi ymmärtää koodia.
Esimerkiksi:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include "allegro.h" /* Älä välitä tästä jos et käytä Allegroa */

typedef struct tietue {
 char nimi[25];
 int arvo;
} TIETUE;

typedef struct tietue2 {
 char nimi[25];
 int arvo;
 struct tietue2 *seur;
} listaTIETUE;

void luo(void);
listaTIETUE *poista(char *, listaTIETUE*);
void poistaminen(void);
void listaakaikki(void);

void luo(void) {
 TIETUE persoona;
 FILE *tiedosto;
 char jatko[8];
 tiedosto = fopen("data", "ab");
 if(tiedosto==NULL) {
  clrscr();
  printf("\nAvaus ei onnistunut!\n");
  getch();
  clrscr();
  exit(1);
 }
 do {
  clrscr();
  printf("Anna nimi: ");
  fgets(persoona.nimi, 24, stdin);
  persoona.nimi[strlen(persoona.nimi)-1]='\0';
  printf("Anna arvo: ");
  scanf("%d%*c", &persoona.arvo);
  fwrite(&persoona, sizeof(persoona), 1, tiedosto);
  printf("Jatketaanko? (k/e): ");
  scanf("%s%*c", jatko);
 }
 while (jatko[0]=='k' || jatko[0]=='K');
 fclose(tiedosto);
}

int main(void) {
 listaTIETUE *henkilo, *eka = NULL;
 int mode;
 // allegro_init();
 // install_keyboard();
 // fade_out(3);
 // set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
 // fade_in(default_palette, 3);
 // textout_centre(screen, font, "This program is protected...", SCREEN_W / 2, (SCREEN_H - 8) / 2, makecol(255, 0, 0));
 // readkey();
 // fade_out(3);
 // clear_bitmap(screen);
 // fade_in(default_palette, 3);
 // allegro_exit();
 do {
  clrscr();
  printf("Tämä on testi...\n\n");
  printf("1 Lisää tietue...\n");
  printf("2 Poista tietue...\n");
  printf("3 Näytä tietueet...\n");
  printf("0 Lopeta...\n\n");
  printf("Valitse toiminto? ");
  scanf("%d%*c", &mode);
  switch (mode) {
   case 1:
    luo();
    break;
   case 2:
    poistaminen();
    break;
   case 3:
    listaakaikki();
    break;
   case 0:
    clrscr();
    exit(0);
    break;
   default:
    ;
  }
 }
 while (mode != 0)
  ;
 while (henkilo!=NULL) {
  eka = henkilo->seur;
  free(henkilo);
  henkilo = eka;
 }
 return 0;
}

listaTIETUE *poista(char *nimi, listaTIETUE *eka) {
 listaTIETUE *henkilo, *edellinen;
 int eri,loysi=0;
 henkilo = eka;
 edellinen = NULL;
 while (henkilo!=NULL) {
  eri = strcmp(henkilo->nimi, nimi);
  if (!eri) {
   if (!edellinen) {
    clrscr();
    printf("Poistetaan listalta nimi \"%s\"\n", nimi);
    eka = henkilo->seur;
    free(henkilo);
    henkilo = eka;
    loysi=1;
    getch();
   }
   else {
    clrscr();
    printf("Poistetaan listalta nimi %s\n", nimi);
    edellinen->seur = henkilo->seur;
    free(henkilo);
    henkilo = edellinen->seur;
    loysi=1;
    getch();
   }
   clrscr();
   printf("OK\n");
   getch();
  }
  else {
   edellinen = henkilo;
   henkilo = henkilo->seur;
  }
 }
 if (loysi==0) {
  clrscr();
  printf("Poistettavaa: \"%s\" ei löytynyt\n", nimi);
  getch();
 }
 return eka;
}

void poistaminen(void)
{
 TIETUE persoona;
 listaTIETUE *henkilo, *eka = NULL;
 FILE *tiedosto;
 size_t maara;
 char nimi[35];
 tiedosto = fopen("data", "rb");
 maara = fread(&persoona, sizeof(persoona), 1, tiedosto);
 if (maara != 0) {
  while (maara == 1) {
   henkilo = (listaTIETUE*)malloc(sizeof(listaTIETUE));
   strcpy(henkilo->nimi, persoona.nimi);
   henkilo->arvo = persoona.arvo;
   if (eka == NULL) {
    eka = henkilo;
    henkilo->seur = NULL;
   }
   else {
    henkilo->seur = eka;
    eka = henkilo;
   }
   maara = fread(&persoona, sizeof(persoona), 1, tiedosto);
  }
  clrscr();
  printf("\nMinkä niminen nimi poistetaan? ");
  fgets(nimi, 34, stdin);
  nimi[strlen(nimi) - 1] = '\0';
  eka = poista(nimi, eka);
  henkilo = eka;
  tiedosto = fopen("data", "wb");
  while (henkilo != NULL) {
   strcpy(persoona.nimi, henkilo->nimi);
   persoona.arvo = henkilo->arvo;
   fwrite(&persoona, sizeof(persoona), 1, tiedosto);
   henkilo = henkilo->seur;
  }
 }
 fclose(tiedosto);
}

void listaakaikki(void) {
 TIETUE persoona;
 listaTIETUE *henkilo, *eka=NULL;
 FILE *tiedosto;
 size_t maara;
 tiedosto = fopen("data", "rb");
 if (tiedosto == NULL) {
  clrscr();
  printf("Tiedostoa ei loytynyt.\n");
  getch();
 }
 else {
  clrscr();
  printf("\nKaikki tiedostossa olevat tietueet:\n\n");
  maara=fread(&persoona, sizeof(persoona), 1, tiedosto);
  if (maara != 0) {
   while(maara==1) {
    henkilo=(listaTIETUE*)malloc(sizeof(listaTIETUE));
    strcpy(henkilo->nimi, persoona.nimi);
    henkilo->arvo = persoona.arvo;
    if (eka==NULL) {
     eka = henkilo;
     henkilo->seur = NULL;
    }
    else {
     henkilo->seur = eka;
     eka = henkilo;
    }
    maara=fread(&persoona, sizeof(persoona), 1, tiedosto);
   }
   while (henkilo!=NULL) {
    printf("Nimi: %-16s Arvo: %-7d\n", henkilo->nimi, henkilo->arvo);
    henkilo = henkilo->seur;
   }
   getch();
  }
 }
}

Kannattaa vilkaista binääriä: http://www.freewebs.com/dungeon86/ohjelmat/struct.exe

timok16 [05.02.2005 13:48:11]

#

kiitos kovasti tästä koodista ja avustasi. siis en tee tästä
copy paste versiota, eli yritän vielä räpeltää tota aikaisempaa tekelettäni, ja olisin kovasti kiitollinen jos saisin siihen ongelmaani avustusta Teiltä, jotka osaavat koodia jo paremmin. Jos sinua kiinnostaa olla henk. kohtainen
avustajani? mahdollisuus mukavaan "rivien mukaan" saatavaan korvaukseen.
ps. kun tulee jumi jossain kohtaa koodia, niin jotenkin sitä vaan pyörittelee sitä jumia ja eikä pääse millään ratkaisuun.

Metabolix [05.02.2005 14:45:49]

#

Enpä jaksa tuohon dungeon86:n koodiin perehtyä, mutta suhteellisen sotkuiselta näyttää, ei millään pahalla. Jos tuo olisi siistimmin kirjoitettu ja edes jossakin määrin kommentoitu, tuon kahlaisi läpi alle minuutissa ja siitä voisi asiaa osaamatonkin helpommin oppia.

Minusta on aivan turha väittää, että C olisi jotenkin selkeämpi kuin C++. Jos ohjelma on C:tä, se kääntyy ihan hyvin myös C++:na, joten on täysin ohjelmoijasta kiinni, miten selkeää koodi on. Sitä paitsi C++:n luokat ovat usein huomattavan helppo tie tehdä asioita, jotka C:llä vaatisivat paljon enemmän tilaa.

Ja ei millään pahalla, dungeon86, mutta en menisi sinuna (ilmeisesti puolisen vuotta C:llä koodanneena) sanomaan, mikä kieli / ohjelmointitapa / tms on hyvä / huono. Eri ihmiset hallitsevat eri asioita hyvin, joten jos sinusta jokin on sekavaa / vaikeaa, se voi monen muun mielestä olla aivan helppoa ja selkeää, tai päinvastoin.

timok16 [05.02.2005 16:14:05]

#

moi,
entäpä toi minun apuni, jota tässä olen pyydellyt jo jonkun aikaa, siis noi yllä mainitut koodin pätkät ja kysymykset
"ala turpo16" . Olisko joku niin ystävällinen ja perehtyisi näihin minun ongelmiini?
Esim. "turpo16 [04.02.2005 13:09:53" kohdan kysymyksiin olis kiva saada asiantuntevilta vastauksia.

Metabolix [05.02.2005 18:34:54]

#

No paha tuohon on tuolta pohjalta sanoa mitään. Mistä tiedät, ettei ohjelma mene siihen funktioon? Laitapa sen toisen funktion alkuun joku cout << "Toinen funktio"; jos et ole vielä niin tehnyt. Jollakin tavalla väärin kuitenkin sitä funktiota ilmeisesti käytät.

Minulla ainakin tämän koodin tulostus on "10, 11", eli toimintaperiaate funktioiden kanssa on tämä (sama, jonka rutkis jo esittikin:

#include <iostream>
using std::cout;

// Struktuurin määrittely
struct TTyyppi_A
{
	int A, B;
	void Aseta();
	void Printtaa();
};

// Toinen struktuuri, joka sisältää ensimmäisen
struct TTyyppi_B
{
	TTyyppi_A Jasen;
	void Aseta();
	void Printtaa();
};

// Funktio, joka asettaa A:ksi 10 ja B:ksi 11.
void TTyyppi_A::Aseta()
{
	this->A = 10;
	this->B = 11;
}

// Funktio, joka tulostaa luvut "A, B"
void TTyyppi_A::Printtaa()
{
	cout << A << ", " << B;
}

// Nämä kutsuvat jäsenenä olevan A-tyypin vastaavia funktioita
void TTyyppi_B::Aseta()
{
	Jasen.Aseta();
}

void TTyyppi_B::Printtaa()
{
	Jasen.Printtaa();
}

int main()
{
	TTyyppi_B L;
	L.Aseta();
	L.Printtaa();
	return 0;
}

timok16 [05.02.2005 20:04:02]

#

kiitos kaunis sinulle. Nyt sain homman pelaamaan. Tätä olen jo pari päivää pyöritellyt, eli todella kaunis kiitos sinulle: ). Olet aina ollut asiallinen ja todella ammattitaitoista apua antava "putkan" käyttäjä.
Homma ratkes siihen kun laitoin kaikki structit samaan headeriin ja näköjään järjestykselläkin on väliä kuinka ne on asetettu sinne.

Metabolix [05.02.2005 20:15:58]

#

Tuo järjestys on tosiaan tietyssä määrin merkityksellinen. Jos eri structien funktiot käyttävät kaikki toisiaan, hommasta selviää näin:

// Kerrotaan, että on olemassa struct-tyypit A_struct ja B_struct
struct A_struct;
struct B_struct;

// Määritellään sisällöt
struct A_struct
{
  // Tämän voi määritellä, koska ylempänä on kerrottu, että B_struct on olemassa
  B_struct B_tyyppinen_struct;
  void JokuFunktio();
};
struct B_struct
{
  A_struct *A_struct_pointer;
  void JokuFunktio();
};

// Funktiot
void A_struct::JokuFunktio()
{
  // Tätä voi kutsua, koska B_structin määrittely on ylempänä.
  B_tyyppinen_struct.Jokufunktio();
}

void B_struct::JokuFunktio()
{
  cout << "void B_struct::JokuFunktio() kutsuttu.\n";
}

Ei ole mierkitystä, missä tiedostossa mikäkin palanen on, jokaisen rivin tai vaikka jokaisen sanan voi halutessaan laittaa vaikka omaan tiedostoonsa, kunhan ne menevät oikeaan järjestykseen includeissa. Esikääntäjä vain kokoaa sen kaiken enemmän tai vähemmän samaan kasaan, eli #include <tiedosto> liittää kyseisen tiedoston siihen kohti koodia.

timok16 [05.02.2005 21:38:12]

#

/* kuinka saisin ton num-muuttujan sijoitettua asiakas.astunnus-kenttään, niin, että se myös näkyy listauksessa?*/
 char astun[7];
      long asnro;
      long numero;
      ifstream inputfile("tunnus1.txt");
                    // tarkistetaan onko tiedosto olemassa
                   if ( !inputfile )
                   {
                      cout << "Tiedoston tunnus1.txt avaus ei onnistunut" << endl;
                    }
                     else
                     {
                        char nro[7];
                        while ( inputfile.getline(asiakas.astunnus,7))
                        {
                           cout<<"Asiakastunnus on. "<<asiakas.astunnus<<endl;//nyt merkkijono

                        numero = atol(asiakas.astunnus);

                        cout<<"Asikastunnus on: "<<numero<<endl;//nyt long-tyyppinen
                        numero=numero + 1;
                        cout<<"Asikastunnus on: "<<numero<<endl;//nyt kasvatettu yhdella

                        itoa(numero,asiakas.astunnus,10);
                        cout<<"Asikastunnus on: "<<asiakas.astunnus<<endl;//nyt taas merkkijonona
                        //kuinka saan nro-muuttujan tiedot tietueen asiakas.astunnus-kenttään

                        }
                      }
                     inputfile.close();

                        ofstream numba ("tunnus1.txt");
                        if (numba.is_open())
                        {
                           numba << asiakas.astunnus<<endl;
                           cout<<"astunnus nyt: "<<asiakas.astunnus<<endl;
                        numba.close();
                        }

Metabolix [05.02.2005 22:35:15]

#

Jaa, minkähän num-muuttujan? Jos kysymys oli kuitenkin tuosta nro-muuttujasta, voit kopioida tiedot vaikka memory.h:sta löytyvällä memcpy-funktiolla: memcpy(asiakas.astunnus, nro, 7);, jossa 7 on kopioitavien tavujen määrä. Ihmettelen kuitenkin, miksi tuon muuttujan haluaisit kopioida, kun et ole edes laittanut siihen mitään.

P.S. Koodin voisi sisentää selvemminkin :)

thefox [06.02.2005 03:08:21]

#

memory.h ei ole standardia; mieluummin string.h.

timok16 [06.02.2005 10:49:54]

#

joo, kiiti taas kovasti. olin jo illalla hiukka väsy, eli annoin vähän hätäisesti ton koodin pätkän näytille. mutta sain taas apua, käyttäen tota mencpy-funktiota pääsin haluttuun tulokseen.

long astun;
	long asnro;
	char apunro[7];
		ifstream inputfile("tunnus1.txt");
  						// tarkistetaan onko tiedosto olemassa
 						if ( !inputfile )
 						{
 							cout << "Tiedoston tunnus1.txt avaus ei onnistunut" << endl;
  						}
							else
							{
								char nro[80];
								while ( inputfile.getline(nro,80))
								{
								astun = atof(nro);
							asnro=astun;
								if(asnro==astun)
 								asnro = asnro+1;
							cout <<"asiakastunnus: "<< asnro << endl;
								}
 							}
							inputfile.close();
								ofstream numero ("tunnus1.txt");
								if (numero.is_open())
								{
								numero << asnro<<endl;
								numero.close();
								}
							itoa(asnro,apunro,10);

		 memcpy(asiakas.astunnus, apunro,7);

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta