Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: tietueiden välinen viiteyhteys

timok16 [14.02.2005 19:10:13]

#

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

struct TT ttietue ;
FILE *ttfileptr;
FILE *tiavaus;
FILE *tuavaus;

void TT::KysyTilausnumero()
{
   char jatko;

      do{
      printf( "\nAnna tilausnumero (6 merkkia): \n");
      cin>>ws;
      scanf ("%s",&ttietue.ttilnro);
      }while(strlen (ttietue.ttilnro) != 6);

      do{
      printf( "\nAnna tuotenumero (6 merkkia): \n");
      cin>>ws;
      scanf ("%s",&ttietue.ttcode);
      }while(strlen (ttietue.ttcode) != 6);

      printf("Anna maara/tuote ");
      scanf("%d", &ttietue.maara);

      kirjoita_levylle();

      printf("Onko lisaa tuotteita? (k/e)");
      scanf("%s" , &jatko);
      if(jatko=='k')
      KysyTilausnumero();
}
void TT::kirjoita_levylle()
{
         if(fseek(ttfileptr, 0, SEEK_END) == 0 ) fwrite(&ttietue, sizeof(ttietue), 1, ttfileptr);
}
int TT::etsi_tilaus(char *apu)
{
         if (fseek(tiavaus, 0, SEEK_SET) == 0) {
         fread(&tilausviite, sizeof(tilausviite), 1, tiavaus);
         while ((strcmp(tilausviite.tilnro, apu) != 0) && (!feof(tiavaus))) {
         fread(&tilausviite, sizeof(tilausviite), 1, tiavaus);
         }
   }
         return 0;
}

int TT::etsi_tuote(char *apu)
{
         if (fseek(tuavaus, 0, SEEK_SET) == 0) {
         fread(&tuoteviite, sizeof(tuoteviite), 1, tuavaus);
         while ((strcmp(tuoteviite.code, apu) != 0) && (!feof(tuavaus))) {

         fread(&tuoteviite, sizeof(tuoteviite), 1, tuavaus);
      }
         return 0;

}
int TT::etsi_tt(char *apu)
{
      if (fseek(ttfileptr, 0, SEEK_SET) == 0) {
         fread(&ttietue, sizeof(ttietue), 1, ttfileptr);
         while ((strcmp(ttietue.ttilnro, apu) != 0) && (!feof(ttfileptr))) {
         fread(&ttietue, sizeof(ttietue), 1, ttfileptr);
         }
   }
      return 0;
}
void TT::maara_summa()
{
   printf("Tuotetta tilattu:  %d\n", ttietue.maara);
   ttietue.summa = tuoteviite.price * ttietue.maara;
   printf("Tilaukset yhteensa: %.2lf\n", ttietue.summa);
}
void TT::list_all()
//listataan kaikki tt sisalto
{
   if (fseek(ttfileptr, 0, SEEK_SET) == 0) {
      while (fread(&ttietue, sizeof(ttietue), 1, ttfileptr) == 1) sisalto();
   }
}

void TT::list_kaikkitilaukset()
//listataan kaikki
{

   if (fseek(tiavaus, 0, SEEK_SET) == 0) {
      while (fread(&tilausviite, sizeof(tilausviite), 1, tiavaus) == 1)list_tilaus();
   }

}
void TT::list_tilaus()
{
      if   (strcmp(tilausviite.tilnro,"      ")) {
      printf("Asiakastunnus : %s\n", tilausviite.astunnus);
      printf("Tilauksen numero on: %s\n", tilausviite.tilnro);
      printf("Tilauspaiva on: %s\n", tilausviite.tilpva);
      printf("Toimituspaiva: %s\n\n", tilausviite.toimpva);
      }

}
void TT::list_kaikkituotteet()
{

   if (fseek(tuavaus, 0, SEEK_SET) == 0) {
      while (fread(&tuoteviite, sizeof(tuoteviite), 1, tuavaus) == 1)lue_tuote();
   }

}

void TT::lue_tuote()
{

      if (strcmp(tuoteviite.code,"      ")) {
      printf("Tuotteen numero on: %s\n", tuoteviite.code);
      printf("Tuotteen nimi on: %s\n", tuoteviite.name);
      printf("Tuotteen hinta on: %.2lf\n", tuoteviite.price);
      printf("Tuotteen lisatiedot ovat: %s\n\n", tuoteviite.lisat);
      }
      //maara_summa();
}

int TT::get_ttchoice()
//näyttää valikot ja palauttaa käyttäjän valinnan
{

   int c=0;
   printf("\n\n ------ MENU ------ \n\n");
   printf("Valitse ja paina Enter\n\n");
   printf(" 1. Nayta kaikki tilaukset ja tuotteet\n");
   printf(" 2. Lisaa tilaukseen tuote\n");
   printf(" 3. Etsi tilaus\n");///
   printf(" 0. Paavalikko\n\n");
   printf(" Valinta > ");
   scanf(" %d", &c);
   return c;
}

void TT::TTValikko()
{
   int c;
        char papu[7];

         //luodaan tiedosto lukemista ja kirjoittamista varten
    if((ttfileptr = fopen("tuotteet_tilaukset.dat","r+b")) == NULL) {
      if ((ttfileptr = fopen("tuotteet_tilaukset.dat","w+b")) == NULL) {
        printf("\nTiedostoa ei olemassa\n");
        exit (0);
      }
   }
      if ((tuavaus = fopen("Tuotteet.dat","r+b")) == NULL) {
      if ((tuavaus = fopen("Tuotteet.dat.dat","w+b")) == NULL) {
        printf("\nTiedostoa ei olemassa\n");
        exit (0);
         }
      }
      if ((tiavaus = fopen("Tilaukset.dat","r+b")) == NULL) {
        printf("\nTiedostoa ei olemassa\n");
        exit (0);
         }

   do
   {
      c = get_ttchoice();
      switch (c)
      {
         case 1:   list_kaikkitilaukset(),list_kaikkituotteet();
               break;

         case 2:   KysyTilausnumero();
                break;

            case 3:  do{
                printf( "\nAnna tilausnumero (6 merkkia): \n");
                cin>>ws;
                scanf ("%s",&papu);
                }while(strlen (papu) != 6);
                  etsi_tt(papu);
                  //sisalto();
                  etsi_tilaus(papu);
                  list_tilaus();
                  memcpy(papu,ttietue.ttcode,7);
                  etsi_tuote(papu);
                  lue_tuote();
                  maara_summa();
                  break;

         case 4:      list_all();
                  break;
         case 0:
               break;
         default: printf(" Virheellinen valinta!\n\n");
      }
   } while (c != 0);
   fclose(tiavaus);
   fclose(tuavaus);
   fclose(ttfileptr);
}

Anna lähtötietona tilausnumeron, tuotenumeron (t),määrän, jotka talletan tiedostoon "tuotteet_tilaukset.dat".
Tämän jälkeen olisi tarkoitus hakea tietyn tilausnumeron alle viittaavat tuotteet.
Koodini on siitä puutteellinen, että ei hae kuin yhden tuotteen/ tilaus. Pitäis pystyä löytämään useampikin tuote/tilaus.
Sitä kysynkin teiltä, että kuinka toi viiteeheys pitäis tehdä?

rutkis [15.02.2005 09:13:01]

#

Talletat jokaisen tilauksen tuotteen erikseen samalla tilausnumerolla.

Tosin tunnut tekevän varsin laajaa tietojärjestelmää joten suosittelisin käyttämään jotakin SQL tietokantaa tuotteiden tallennukseen/lukemiseen. Esim MySQL.

timok16 [15.02.2005 10:18:50]

#

Taas vallan mainioita vastauksia teiltä osaajilta. Tämähän auttaa tosissaan minua todella paljon?
Ystävällisesti vielä kysyn että, kuinka tämä ongelmani ratkeaa tässä minun koodissani ilman että käytän mitään
sql-tietokantaa?

sqwiik [15.02.2005 16:10:19]

#

Muunna etsimiä ottamaan toinenkin parametri, joka kertoo monesko löydetty huomioidaan. Muunnettu koodi etsimisestä (voit itse muuntaa loput kohdat):

/*
  Käyttö: esim. etsi_tilaus(apu, 0) etsii ensimmäisen, (apu, 1) toisen jne. Jos
  mones on liian suuri (tai negatiivinen), palauttaa automaattisesti viimeisen löydetyn.
*/
int TT::etsi_tilaus(char *apu, int mones){
int loyd = 0; // Montako on jo löydetty
  if (fseek(tiavaus, 0, SEEK_SET) == 0){
    while (!feof(tiavaus)){
      fread(&tilausviite, sizeof(tilausviite), 1, tiavaus);
      /* Onko luettu tietue oikea? == 0, jos on */
      if(strcmp(tilausviite.tilnro, apu) == 0){
        /* Lopetetaan jos löytyi oikea */
        if(loyd == mones)break;
        loyd ++;
      }
    }
  }
  return 0;
}

Tuota voi hyödyntää esim. seuraavasti: luet ensin montako tuotetta tiedostossa on ja ajat tuon hakijan yhtä monta kertaa (kasvavalla mones-arvolla). Näin koodi huomioi kaikki mahdolliset tapaukset, mutta aina on optimoinnin varaa.

timok16 [15.02.2005 16:28:44]

#

kiitos sqwiik.
ratkaisin sen itse hiukan juuri tuohon tapaan kuin sinä yllä
laitoit. Onhan täällä aitoa osaamistakin, eikä vain ylimielistä kommenttia kyselyihin.
Kiitos vielä kerran sinulle. Olet asiallinen auttaja.

timok16 [16.02.2005 11:46:35]

#

/* globaalit muuttujat- ja funktioiden esittelyt */
struct TUOTE {
	char code[7];
	char name[30];
	double price;
	char lisat[251];

	void get_product();
	void add_product();
	int find_product(char *pcode);
	void update_product();
	void delete_product();
	int get_pchoice();
	void list_product();
	void list_pall();
	void TuoteValikko();
};

struct TILAUS {

	char tilnro[7];
	char tilpva[11];
	char toimpva[11];
	char astunnus[7];
	char apunro[7];
	long numero;

	void get_tilaus();
	int find_tilaus(char *ptilnro);
	void update_tilaus();
	void delete_tilaus();
	int get_tchoice();
	void list_tilaus();
	void list_tall();
	void TilausValikko();

};
struct ASIAKAS {

	TILAUS apu;  //TILAUS-tyyppinen apu-muuttuja
	char address[21];
	char postcode[6];
	char city[21];
	char asnimi[31];
	char astunnus[7];

	void get_asnimi();
	int find_asnimi(char *pastunnus);
	void update_asnimi();
	void delete_asnimi();
	int get_choice();
	void list_asnimi();
	void list_all();
	int AsiakasValikko();
	void TilausValikko();
};

struct TT {
	TUOTE tuoteviite;
	TILAUS tilausviite;
	void TTValikko();
	int get_ttchoice();
	void list_tilaus();
	void lue_tuote();
	void KysyTilausnumero();

	int etsi_tt(char *apu);

	void sisalto();
	void list_all();
	void kirjoita_levylle();
	void jatka_kyselya();
	void delete_tuote_tilaus();
	int etsi_tuote_tilaus(char *ttapu);

	int etsi_tilkohta5(char *tilalku_kohta, char *tilloppu_kohta);


	int etsi_tilaus(char *apu);
	int etsi_tuote(char *tapu);
	void maara_summa();

	char ttilnro[7];
	char ttcode[7];
	int maara;
	double summa;

};

int TT::etsi_tilkohta5(char *tilalku_kohta, char *tilloppu_kohta)
{
			if (fseek(tiavaus, 0, SEEK_SET) == 0) {
			fread(&tilausviite, sizeof(tilausviite), 1, tiavaus);
			while (tilausviite.tilpva >= tilalku_kohta && tilausviite.tilpva <= tilloppu_kohta /*&&(!feof(tiavaus)*/) {
			fread(&tilausviite, sizeof(tilausviite), 1, tiavaus);
			}
			if (tilausviite.tilpva >= tilalku_kohta && tilausviite.tilpva <= tilloppu_kohta ) {
			fseek(tiavaus, -(sizeof(tilausviite)),SEEK_CUR);

			return 1;
			} else return 0;
	}
			return 0;
}

	char ptilalku_kohta[11];
	char ptilloppu_kohta[11];


	case 5:	do{
					printf( "\nAnna alkupaiva: (syota muodossa pp.kk.vvvv)\n");
					cin>>ws;
					gets(ptilalku_kohta);
					}while(strlen (ptilalku_kohta) != 10);

					do{
					printf( "\nAnna loppupaiva: (syota muodossa pp.kk.vvvv)\n");
					cin>>ws;
					gets(ptilloppu_kohta);
					}while(strlen (ptilloppu_kohta) != 10);

					if(fseek(ttfileptr, 0, SEEK_SET)==0){
					while((etsi_tt(papu)==1) && (!feof(ttfileptr))){
						etsi_tilkohta5(ptilalku_kohta,ptilloppu_kohta);
						list_tilaus();

tässä nää struct:it
nyt ongelma että pitäis tulostaa tietyllä aikavälillä
tehtyjen tilausten yhteissumma. Tässä hiukka alkua, ei siis
vielä lähelläkään toteutusta. olenko ihan hukassa, jos yritän sitä näin tehdä?

Vastaus

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

Tietoa sivustosta