Apua tarvitaan koodiin

Koodiin pitäisi lisätä lajittelu joka lajittelee levyt aakkosjärjestykseen, ensin levyn nimen mukaan, ja saman artistin levyt levyn nimen mukaan.

Vielä pitäisi päästä muuttamaan arvosanaa erikseen jälkikäteen.

Olen tähän saakka saanut tehtyä seuraavanlaisen vedoksen. Osaisiko ja viitsisikö joku auttaa noiden parin toiminnon kanssa?

#include
#include
#include
#include

/*Maaritellaan kaytettavien kenttien koot*/
#define KOKO 50
#define PITUUS 20
#define MAX 500
/*Esitellaan funktio*/
void valikko();
void lisaa();
void selaa();
void etsi();
void poista();
void muuta();
void jarjestele();
void poistu();
char tietue_koko[MAX];
/*Muuttujat*/
struct tietokanta
{
   char levy [KOKO] ;
   char artisti [KOKO] ;
   char vuosi [PITUUS];
   char arvosana [PITUUS];
   char Kohde[KOKO];

} tietokanta;

/*Kaytettavat tietuenimet*/
FILE *Tiedot;
FILE *temppi;

/****************************************************************************************************/

/*PAAOHJELMA*/
int main(void)
{      
   int valinta=0;
   
      /*tyhjennetaan ruutu*/
      system("cls");
      
      /*paavalikko*/
      valikko();
      printf("Valitse toiminto: ");
      scanf("%i",&valinta);
      fflush(stdin);
      
      /*valinta toteutettu case-periaatteella*/
   switch (valinta)
   {   
         case 1:
            {
               system("cls");
               selaa();
            break;
            }

         case 2:
            {
               system("cls");
               lisaa();
            break;
            }
         
         case 3:
            {   system("cls");
               etsi();
            break;
            }

         case 4:
            {   system("cls");
               poista();
            break;
            }
            
         case 5:
            {   system("cls");
               muuta();
            break;
            }

         case 6:
            {   system("cls");
               jarjestele();
            break;
            }

       case 7:
          { system("cls");
            poistu();
         break;
         }
      default:
         {
            printf("Valitse toiminto ainoastaan 1-7 valilta\n"); system("pause");
            system("cls");
         }
   }
}
/******************************************************************************************************/

/*LISTAUS-KOHTA*/
void selaa()
{
      char valinta3;

/*Avataan tiedosto*/
      Tiedot = fopen("Tiedot.txt","a ");
      do
      {
         fgets(tietue_koko,MAX,Tiedot);
         printf("%s\n",tietue_koko);

      }while(!feof(Tiedot));

      /*Pause-komennolla stopataan listaus*/
      system("pause");
      /*Suljetaan tallennus*/
         fclose(Tiedot);
         main();
}
/******************************************************************************************************/

/*TALLENNUS-TOIMINTO*/
void lisaa()
{
      char valinta2;

      /*Avataan tiedosto, ja jos sita ei ole, luodaan se*/
         Tiedot = fopen("Tiedot.txt","a ");

         printf("Anna levyn nimi\n");

         scanf("%s",tietokanta.levy);
         
         printf("Anna artistin nimi\n");

         scanf("%s",tietokanta.artisti);
         
         printf("Anna arvosana\n");

         scanf("%s",tietokanta.arvosana);
         
         printf("Anna julkaisuvuosi\n");

         scanf("%s",tietokanta.vuosi);
         
         /*Tulostetaan tiedostoon (Records.txt) */
         fprintf(Tiedot,"%s %s %s %s \n",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);

         /*Suljetaan tallenna-toiminto*/
         fclose(Tiedot);

         main();
}
/****************************************************************************************************************/

/*PAAVALIKKO*/
void valikko()
{
   /*Valittavat toiminnot*/
      printf("Osoitekirja\n");
      printf("\n");
      printf("Valitse toiminto (1-7)\n");
      printf("\n");
      printf("1=Selaa tietoja\n");
      printf("2=Lisaa tietoja\n");
      printf("3=Etsi tietoja\n");
      printf("4=Poista tietoja\n");
      printf("5=Muuta arvosanaa\n");
      printf("6=Jarjestele tiedot aakkosjarjestykseen\n");
      printf("7=Poistu ohjelmasta\n");
      printf("\n");
}
/***********************************************************************************************/

/*ETSI-TOIMINTO*/
void etsi()
{
   /*Maaritellaan kohteen koko*/
char Kohde[MAX];
   //
   int Found=0;
   if((Tiedot=fopen("Tiedot.txt","r"))==NULL)
   
            printf("Ei tietoja!\n\n");
   
                  else
                  {
                     system("cls");
                     printf("\n\n");
                     printf("Etsi-valikko");
                     printf("\n\n");
                     printf("Valitse etsittava nimi:");
                     /*Otetaan kohde*/
                     scanf("%s",Kohde);
                              while(!feof(Tiedot)&& Found==0)
                                    {
                                       fscanf(Tiedot,"%s %s %s %s ",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);
                                       if(strcmp(Kohde,tietokanta.levy)==0)
                                       Found=1;
                                    }
                                       if(Found)
                                       {
                                          printf(".......tieto loytyi\n");
                                          system("pause");
                                          system("cls");
                                          printf("1 tieto loytyi : \n\n\n");
                                          printf("Levyn nimi: %s\n",tietokanta.levy);
                                          printf("Artistin nimi: %s\n",tietokanta.artisti);
                                          printf("Arvosana: %s\n",tietokanta.arvosana);
                                          printf("Julkaisuvuosi: %s\n",tietokanta.vuosi);
                                          system("pause");

                                       }   
                                       else if(!Found)
                                       {
                                          printf("Valitettavasti tietoja ei loytynyt\n");
                                          system("pause");
                                       }
                                          fclose(Tiedot);
          main();
}
}
/*************************************************************************************************/

/*MUUTA ARVOSANAA-KOHTA*/
   void muuta()
   {
                     printf("Poistutaan ohjelmasta }n");
   }
/***************************************************************************************************/

/*JARJESTELU-TOIMINTO*/
   void jarjestele()
   {
                     printf("Poistutaan ohjelmasta }n");
   }
/*************************************************************************************************/

/*OHJELMASTA POISTUMINEN*/
   void poistu()
   {
                     printf("Poistutaan ohjelmasta }n");
   }
/***************************************************************************************************/

/*TIETOJEN POISTAMINEN*/
   void poista()
{
   /*kohteen koko maaritelty */
char Kohde[MAX];
   int Found=0;
      system("cls");

   temppi=fopen("temppi.txt","w");
   if((Tiedot=fopen("Tiedot.txt","r"))==NULL)
      printf("Ei tietoja!\n\n");
   
               else{
                     printf("\n\n");
                     printf("Poista tietoja-valikko\n");
                     printf("\n\n");
                     printf("Anna poistettava nimi: ");
                     fflush(stdin);
                     gets(Kohde);
         while(!feof(Tiedot))
         {
         fscanf(Tiedot,"%s %s %s %s ",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);
         if(feof(Tiedot))
         break;
      if(strcmp(Kohde,tietokanta.levy)!=0)
         
         fprintf(temppi,"%s %s %s %s \n",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);
                  else {
      
                        Found=1;
                     printf(".......tieto loytyi\n");
                     system("pause");
                     printf("Levyn nimi:%s\n",tietokanta.levy);
                     printf("Artistin nimi:%s\n",tietokanta.artisti);
                     printf("Arvosana: %s\n",tietokanta.arvosana);
                     printf("Julkaisuvuosi: %s\n",tietokanta.vuosi);
                     fflush(stdin);
                     system("pause");
                     }
                     }
         if (!Found)
         {
         printf("Tietoja ei loytynyt\n");/*Ilmoitus, jos tietoja ei loytynyt*/
         }
      printf("Tiedot poistettu\n");
      
      fclose(Tiedot);
      fclose(temppi);
      remove("Tiedot.txt");
      
      rename("temppi.txt","Tiedot.txt");
         main();
   }
   }
261201
Äänestä

Muut lukivat myös

Vastaukset 26

Vanhimmat

http://www.cppreference.com/stdother/qsort.html

Eli lue filun tiedot taulukoon.

Tee vertailu funktiot noille kentille.

shortaa ja kirjoita takaisin.

Mikäli ole ymmärtänyt oikein "tietokannan" rivi näyttää tältä:

"levy artisti vuosi arvosana kohde"

Esim. jos levyn nimessä on välilyönti, luku ei enään onnistu. Fiksumpaa olisi tehdä asia esim csv muodossa:

"levy ; artisti ; vuosi ; arvosana ; kohde"


Ja erotaa kenttät vaikka tällä

http://www.cplusplus.com/reference/clibrary/cstring/strtok.html

vaikka näin:

// palautaa tietokannan koon, taulukko on vakio kokoinen
int lueFilusta(char *filee, tietokanta taulukko[]) {
char buffer[1234];
int indexi = 0;
FILE *fp = fopen(filee,"r");

while(!feof(fp)) {
fgets(buffer,sizof(buffer),fp);
sprintf(taulukko[i].levy,"%s", strtok(buffer,";");

sprintf(taulukko[i].artisti,"%s", strtok(NULL,";");

indexi ++;
}

return indexi;
}

void printaaFiluun(char *filee,tietokanta taulukko[], int koko) {
int i;
FILE *Tiedot = fopen(filee,"w");
for(i = 0; i < koko; i++) {
fprintf(Tiedot,"%s ; %s ; %s ; %s \n",tietokanta[i].levy,tietokanta[i].artisti,tietokanta[i].arvosana,tietokanta[i].vuosi);
}
}

Eli on fiksumpaa lukea koko filu muistiin ja muokata sitä siellä. Esim jos katsot koodiasi huomaat että käytät tiedostoperaatioita aika monessa kohdassa.

en ole varma menikö oiken sillä C kielellä koodailusta on aikaa ;P

Äänestä

(defvar *db* nil)

(defun make-cd (title artist rating ripped)
(list :title title :artist artist :rating rating :ripped ripped))

(defun add-record (cd) (push cd *db*))

(defun dump-db ()
(dolist (cd *db*)
(format t "~{~a:~10t~a~%~}~%" cd)))

(defun prompt-read (prompt)
(format *query-io* "~a: " prompt)
(force-output *query-io*)
(read-line *query-io*))

(defun prompt-for-cd ()
(make-cd
(prompt-read "Title")
(prompt-read "Artist")
(or (parse-integer (prompt-read "Rating") :junk-allowed t) 0)
(y-or-n-p "Ripped [y/n]: ")))

(defun add-cds ()
(loop (add-record (prompt-for-cd))
(if (not (y-or-n-p "Another? [y/n]: ")) (return))))

(defun save-db (filename)
(with-open-file (out filename
:direction :output
:if-exists :supersede)
(with-standard-io-syntax
(print *db* out))))

(defun load-db (filename)
(with-open-file (in filename)
(with-standard-io-syntax
(setf *db* (read in)))))

(defun clear-db () (setq *db* nil))

(defun select (selector-fn)
(remove-if-not selector-fn *db*))

(defmacro where (&rest clauses)
`#'(lambda (cd) (and ,@(make-comparisons-list clauses))))

(defun make-comparisons-list (fields)
(loop while fields
collecting (make-comparison-expr (pop fields) (pop fields))))

(defun make-comparison-expr (field value)
`(equal (getf cd ,field) ,value))


(defun update (selector-fn &key title artist rating (ripped nil ripped-p))
(setf *db*
(mapcar
#'(lambda (row)
(when (funcall selector-fn row)
(if title (setf (getf row :title) title))
(if artist (setf (getf row :artist) artist))
(if rating (setf (getf row :rating) rating))
(if ripped-p (setf (getf row :ripped) ripped)))
row) *db*)))

(defun delete-rows (selector-fn)
(setf *db* (remove-if selector-fn *db*)))

Äänestä

Kutsut aliohjelmissa main(); Ei niin "saa" tehdä: saattaa kääntyä, mutta kuinka suoritus?

Äänestä
  • main on normaali funtio, varsinainen "entrypoint" on mukaan linkatavassa libissä (c0.lib?? tai vastaava).


    Mutta rumaa tuo on.

    Äänestä

Osaisitteko ystävällisesti auttaa tuon koodin "puhtaaksikirjoittamisessa" ja noiden parin puuttuvan toiminnon lisäämisessä?

Äänestä
  • #include
    #include
    #include

    #define KOKO 50
    #define PITUUS 20
    #define MAX_LEVYA 500

    struct henkilo {
       char levy[KOKO];
       char artisti[KOKO];
       char vuosi[PITUUS];
       char arvosana[PITUUS];
    };

    const char rekisteri[] = "luettelo.txt";

    //TiedonKopiointi kopioi tekstin in -> out
    //out - osoitin kohteeseen, in - osoitin lähteeseen
    //koko - tiedon maksimikoko
    //Paluuarvo on
    //- joko osoitin seuraavan tiedon alkuun
    //- tai koko -kentän määräämään osoitteeseen
    char* TiedonKopiointi(char*out, char*in, unsigned koko)
    {
       char* pc, *pc2;
       unsigned j;
       memset(out, 0, koko);
       pc = in;
       pc2 = out;
       for(j = koko; j && *pc != ' ' && *pc != '\n'; --j){
          *pc2 = *pc;
          pc2++;
          pc++;
       }
       return ++pc;
    }

    //TaytaTietue täyttää tietueen yhden rivin
    //buffer - osoitin merkkijonoon, jossa on tiedostosta luettu tekstirivi
    //phenk - osoitin tietueen rivin alkuun
    //Paluuarvona osoitin seuraavaan tietueeseen
    struct henkilo* TaytaTietue(char*buffer, struct henkilo*phenk)
    {
       char* pc;
       pc = buffer;
       pc = TiedonKopiointi(phenk->levy, pc, KOKO);
       pc = TiedonKopiointi(phenk->artisti, pc, KOKO);
       pc = TiedonKopiointi(phenk->vuosi, pc, PITUUS);
       pc = TiedonKopiointi(phenk->arvosana, pc, PITUUS);
       //Tässä kohdassa voisi varmistaa, että ollaan seuraavalla rivillä
       return ++phenk;
    }

    //LueTiedostoMuistiin lukee tiedoston henkilo -tietuetaulukkoon
    //henkilo_lista - henkilo -tietuetaulukon osoite
    unsigned LueTiedostoMuistiin(struct henkilo*henkilo_lista)
    {
       char buffer[sizeof(struct henkilo)];
       FILE *tiedosto;
       int hlomaara = 0;
       struct henkilo* phenk;
       long i;
       if ((tiedosto = fopen(rekisteri, "r")) != NULL) {
          fgets(buffer, 4, tiedosto);
          hlomaara = atoi(buffer);
          if (hlomaara >= MAX_LEVYA) {
             printf("Korkeintaan %d tietuetta", MAX_LEVYA);
             fclose(tiedosto);
             return -1;
          }
          for(i = 1, phenk = henkilo_lista; i = MAX_LEVYA){
          printf("Ei voi lisätä. Maksimimäärä listalla");
          return phenk;
       }
       printf("Anna levyn nimi:");
       LueMerkkijono(phenk->levy, KOKO - 1);
       printf("Anna artisti:");
       LueMerkkijono(phenk->artisti, KOKO - 1);
       printf("Anna ilmestymisvuosi:");
       LueMerkkijono(phenk->vuosi, PITUUS - 1);
       printf("Anna arvosana:");
       LueMerkkijono(phenk->arvosana, PITUUS - 1);
       *maara = *maara + 1;
       return ++phenk;
    }

    //PoistaHenkilo poistaa henkilo -tietuetaulukosta halutun tiedon (rivin)
    //henkilo_lista - osoitin henkilo -tietuetaulukon alkuun
    //phenk - osoitin seuraavaan vapaaseen paikkaan taulukossa
    //hlomaara - osoitin tietojen määrään taulukossa
    //poistettava - poistettavan rivin numero (1 on ensimmäinen)
    //Paluuarvona osoitin seuraavaan vapaaseen tietueeseen ja määrä pienenee
    struct henkilo* PoistaHenkilo(struct henkilo* henkilo_lista, struct henkilo*phenk,
                                                 unsigned* hlomaara, unsigned poistettava)
    {
       struct henkilo *phenk1, *phenk2;
       char* pc, *pc2;
       unsigned i = *hlomaara;
       if(poistettava > i)
          return phenk;
       else if(poistettava != i){ //Onko viimeinen tieto ?
          phenk1 = henkilo_lista;
          phenk1 += (poistettava - 1); //Poistettavan kohdalle
          phenk2 = phenk1;
          phenk2++; //Ensimmäisen siirrettävän kohdalle
          //Siirrä loppuja pykälällä alkuun päin
          pc2 = (char*)(void*)phenk2;
          pc = (char*)(void*)phenk;
          memcpy(phenk1, phenk2, pc - pc2);
       }
       *hlomaara = i - 1;
       return --phenk;
    }

    //TallennaTiedostoon tallentaa henkilo -tietuetaulukon
    //phenk - osoitin ensimmäiseen tietoon tietuetaulukossa
    //maara - tietojen määrä taulukossa
    unsigned TallennaTiedostoon(struct henkilo* phenk, unsigned maara)
    {
       FILE *tiedosto;
       unsigned i;
       if ((tiedosto = fopen(rekisteri, "w")) == NULL) { //Uuden tiedoston luonti
          printf("Virhe tiedoston avaamisessa.");
          return 1;
       }
       fprintf(tiedosto, "%d\n", maara); //Kirjoitettavien määrä tiedoston alkuun
       for(i = maara; i; --i){
          fprintf(tiedosto,"%s %s %s %s\n", phenk->levy, phenk->artisti, phenk->vuosi, phenk->arvosana);
          phenk++;
       }
       fclose(tiedosto);
       printf("Tietojen tallennus onnistui\n");
       return 0;
    }

    //TulostaSisalto tulostaa tietueen sisällön
    //henkilo_lista - osoitin tietueen alkuun
    //maara - tietojen määrä taulukossa
    void TulostaSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned i = maara;
       printf("\n");
       for(i = 1 ; i levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
       }
    }

    //MuutaTietoja
    void MuutaTietoja(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned muutettava;
       char buffer[PITUUS];
       TulostaSisalto(henkilo_lista, maara);
       printf("\nAnna muutettava:");
       fgets(buffer, 4, stdin);
       muutettava = atoi(buffer);
       if(muutettava levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
          printf("\nAnna uusi arvosana:");
          LueMerkkijono(buffer, PITUUS - 1);
          memcpy(phenk->arvosana, buffer, PITUUS);
       }
    }

    //Vertaa antaa listalle järjestyksen
    //eka - osoitin ensimmäiseen henkilo -tietueeseen
    //toka - osoitin toiseen henkilo -tietueeseen
    int Vertaa(const void* eka, const void* toka)
    {
       struct henkilo* phenk1 = (struct henkilo*)eka;
       struct henkilo* phenk2 = (struct henkilo*)toka;
       int i;
       i = stricmp(phenk1->artisti, phenk2->artisti);
       if (!i)
          i = stricmp(phenk1->levy, phenk2->levy);
       return i;
    }

    int main(void)
    {
       struct henkilo henkilo_lista[MAX_LEVYA];
       unsigned hlomaara, poistettava;
       struct henkilo* phenk;
       unsigned i, j;
       
       hlomaara = LueTiedostoMuistiin(henkilo_lista);
       if(hlomaara > (unsigned)-1)
          return 1;

       phenk = henkilo_lista;
       phenk += hlomaara; //Uuden tiedon kohdalle

       i = 0;

       while(!i) {
          char buffer[4], c;
          printf("\n\n\n\n============\nAlkuvalikko\n------------\n"
             "Valitse:\n1 Lisää luetteloon\n2 Poista luettelosta\n"
             "3 Tulosta sisältö\n4 Järjestele\n5 Muokkaa\n\n9 Lopettaa ohjelman\n"
             "------------\nValintasi:");
          switch(c = fgetc(stdin) - '0') {
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 9:
             i = c;
          }
          for(j = c + '0'; j != '\n' && j != EOF; j = fgetc(stdin));
          switch(i) {
          case 1: //Käyttäjältä uusi henkilö
             phenk = UusiHenkilo(phenk, &hlomaara);
             i = 0;
             break;
          case 2: //Poistettavana joku listalta
             TulostaSisalto(henkilo_lista, hlomaara);
             printf("\n\nAnna poistettava:");
             fgets(buffer, 4, stdin);
             poistettava = atoi(buffer);
             phenk = PoistaHenkilo(henkilo_lista, phenk, &hlomaara, poistettava);
             i = 0;
             break;
          case 3: //Tulostaa sisällön
             TulostaSisalto(henkilo_lista, hlomaara);
             i = 0;
             break;
          case 4: //Järjestelee aakkosjärjestykseen
             qsort(henkilo_lista, hlomaara, sizeof(henkilo), Vertaa);
             i = 0;
             break;
          case 5: //Muokkaa tietuetta
             MuutaTietoja(henkilo_lista, hlomaara);
             i = 0;
          }
       }

       //Listan tallennus tiedostoon
       TallennaTiedostoon(henkilo_lista, hlomaara);

       return 0;
    }

    /*
    //Rivin poistaminen muuttuvaleveyksisestä tiedostosta

    int main(void)
    {
    unsigned hlomaara;
    char rekisteri[] = "luettelo.txt";
    FILE *avaus;
    char buffer[3208], *pc;
    unsigned luettumaara;

    if ((avaus = fopen(rekisteri, "r")) != NULL) { //Jos tiedosto on siis olemassa, avataan vain lukuun
    unsigned i, j;
    luettumaara = fread(buffer, 1, 3207, avaus); //Luku
    fclose(avaus);//ja sulkeminen
    if(!luettumaara){
    printf("Tiedosto on väärässä muodossa");
    return 2;
    }
    //Etsitään luettelon alku (oletan että kyseessä on tietynmuotoinen tiedosto ;))
    for(i = luettumaara, pc = buffer;*pc != '\n';pc++, --i);
    pc++; //Koska oltiin rivin vaihdon kohdalla
    --i; //Tässä on tiedosta luettujen henkilo -tietueiden koko
    //Nyt ollaan siis ensimmäisen henkilön kohdalla. Seuraaviin pääsee hakemalla rivinvaihtoa. Muista kuitenkin pienentää i:n arvoa vastaavasti
    //Poistan malliksi ensimmäisen käyttäen siirtomenetelmää
    if(i) {
    char*pc2; //Avuksi toinen osoitin, jota käytetään hakemaan seuraava tietue
    for(pc2 = pc, j = i ; *pc2 != '\n' && j ; pc2++, --j); //Haetaan seuraavaa riviä
    pc2++; //tietueen alkuun
    if(j){ //jos tietueita ei olisi jäljellä, siirtoa ei tarvitsisi tehdä
    --j; //koska pc2:ta kasvatettiin
    memcpy(pc, pc2, j);//Kohde on siis pc, lähde pc2 ja jäljellä olevien tavujen määrä j
    pc += j;//katkaisurajan kohdalle
    }
    pc2 = pc; //pc2 on nyt ensimmäisen poistettavan merkin kohdalla
    //ja sitä määrää pitää taas viilata eli
    hlomaara = atoi(buffer); //alkuperäinen
    hlomaara--; //uusi
    pc = buffer;
    if(hlomaara >= 10){
    *pc = (hlomaara / 10) + '0'; //kymmenet merkikse
    pc[1] = (hlomaara % 10) + '0'; //alle kymmenet merkiksi
    }
    else{
    if(hlomaara == 9) //Tässä numero lyhenee
    pc++;
    *pc = hlomaara + '0'; //ja sama merkkinä
    }
    if ((avaus = fopen(rekisteri, "w")) != NULL) { //Tuhotaan tiedoston alkuperäinen sisältö
    fwrite(pc, 1, pc2 - pc, avaus); //ja kirjoitus takaisin tiedostoon
    fclose(avaus);
    }
    }
    }
    return 0;
    }*/

    Äänestä

  • apuja ongelmaan kirjoitti:

    #include
    #include
    #include

    #define KOKO 50
    #define PITUUS 20
    #define MAX_LEVYA 500

    struct henkilo {
       char levy[KOKO];
       char artisti[KOKO];
       char vuosi[PITUUS];
       char arvosana[PITUUS];
    };

    const char rekisteri[] = "luettelo.txt";

    //TiedonKopiointi kopioi tekstin in -> out
    //out - osoitin kohteeseen, in - osoitin lähteeseen
    //koko - tiedon maksimikoko
    //Paluuarvo on
    //- joko osoitin seuraavan tiedon alkuun
    //- tai koko -kentän määräämään osoitteeseen
    char* TiedonKopiointi(char*out, char*in, unsigned koko)
    {
       char* pc, *pc2;
       unsigned j;
       memset(out, 0, koko);
       pc = in;
       pc2 = out;
       for(j = koko; j && *pc != ' ' && *pc != '\n'; --j){
          *pc2 = *pc;
          pc2++;
          pc++;
       }
       return ++pc;
    }

    //TaytaTietue täyttää tietueen yhden rivin
    //buffer - osoitin merkkijonoon, jossa on tiedostosta luettu tekstirivi
    //phenk - osoitin tietueen rivin alkuun
    //Paluuarvona osoitin seuraavaan tietueeseen
    struct henkilo* TaytaTietue(char*buffer, struct henkilo*phenk)
    {
       char* pc;
       pc = buffer;
       pc = TiedonKopiointi(phenk->levy, pc, KOKO);
       pc = TiedonKopiointi(phenk->artisti, pc, KOKO);
       pc = TiedonKopiointi(phenk->vuosi, pc, PITUUS);
       pc = TiedonKopiointi(phenk->arvosana, pc, PITUUS);
       //Tässä kohdassa voisi varmistaa, että ollaan seuraavalla rivillä
       return ++phenk;
    }

    //LueTiedostoMuistiin lukee tiedoston henkilo -tietuetaulukkoon
    //henkilo_lista - henkilo -tietuetaulukon osoite
    unsigned LueTiedostoMuistiin(struct henkilo*henkilo_lista)
    {
       char buffer[sizeof(struct henkilo)];
       FILE *tiedosto;
       int hlomaara = 0;
       struct henkilo* phenk;
       long i;
       if ((tiedosto = fopen(rekisteri, "r")) != NULL) {
          fgets(buffer, 4, tiedosto);
          hlomaara = atoi(buffer);
          if (hlomaara >= MAX_LEVYA) {
             printf("Korkeintaan %d tietuetta", MAX_LEVYA);
             fclose(tiedosto);
             return -1;
          }
          for(i = 1, phenk = henkilo_lista; i = MAX_LEVYA){
          printf("Ei voi lisätä. Maksimimäärä listalla");
          return phenk;
       }
       printf("Anna levyn nimi:");
       LueMerkkijono(phenk->levy, KOKO - 1);
       printf("Anna artisti:");
       LueMerkkijono(phenk->artisti, KOKO - 1);
       printf("Anna ilmestymisvuosi:");
       LueMerkkijono(phenk->vuosi, PITUUS - 1);
       printf("Anna arvosana:");
       LueMerkkijono(phenk->arvosana, PITUUS - 1);
       *maara = *maara + 1;
       return ++phenk;
    }

    //PoistaHenkilo poistaa henkilo -tietuetaulukosta halutun tiedon (rivin)
    //henkilo_lista - osoitin henkilo -tietuetaulukon alkuun
    //phenk - osoitin seuraavaan vapaaseen paikkaan taulukossa
    //hlomaara - osoitin tietojen määrään taulukossa
    //poistettava - poistettavan rivin numero (1 on ensimmäinen)
    //Paluuarvona osoitin seuraavaan vapaaseen tietueeseen ja määrä pienenee
    struct henkilo* PoistaHenkilo(struct henkilo* henkilo_lista, struct henkilo*phenk,
                                                 unsigned* hlomaara, unsigned poistettava)
    {
       struct henkilo *phenk1, *phenk2;
       char* pc, *pc2;
       unsigned i = *hlomaara;
       if(poistettava > i)
          return phenk;
       else if(poistettava != i){ //Onko viimeinen tieto ?
          phenk1 = henkilo_lista;
          phenk1 += (poistettava - 1); //Poistettavan kohdalle
          phenk2 = phenk1;
          phenk2++; //Ensimmäisen siirrettävän kohdalle
          //Siirrä loppuja pykälällä alkuun päin
          pc2 = (char*)(void*)phenk2;
          pc = (char*)(void*)phenk;
          memcpy(phenk1, phenk2, pc - pc2);
       }
       *hlomaara = i - 1;
       return --phenk;
    }

    //TallennaTiedostoon tallentaa henkilo -tietuetaulukon
    //phenk - osoitin ensimmäiseen tietoon tietuetaulukossa
    //maara - tietojen määrä taulukossa
    unsigned TallennaTiedostoon(struct henkilo* phenk, unsigned maara)
    {
       FILE *tiedosto;
       unsigned i;
       if ((tiedosto = fopen(rekisteri, "w")) == NULL) { //Uuden tiedoston luonti
          printf("Virhe tiedoston avaamisessa.");
          return 1;
       }
       fprintf(tiedosto, "%d\n", maara); //Kirjoitettavien määrä tiedoston alkuun
       for(i = maara; i; --i){
          fprintf(tiedosto,"%s %s %s %s\n", phenk->levy, phenk->artisti, phenk->vuosi, phenk->arvosana);
          phenk++;
       }
       fclose(tiedosto);
       printf("Tietojen tallennus onnistui\n");
       return 0;
    }

    //TulostaSisalto tulostaa tietueen sisällön
    //henkilo_lista - osoitin tietueen alkuun
    //maara - tietojen määrä taulukossa
    void TulostaSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned i = maara;
       printf("\n");
       for(i = 1 ; i levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
       }
    }

    //MuutaTietoja
    void MuutaTietoja(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned muutettava;
       char buffer[PITUUS];
       TulostaSisalto(henkilo_lista, maara);
       printf("\nAnna muutettava:");
       fgets(buffer, 4, stdin);
       muutettava = atoi(buffer);
       if(muutettava levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
          printf("\nAnna uusi arvosana:");
          LueMerkkijono(buffer, PITUUS - 1);
          memcpy(phenk->arvosana, buffer, PITUUS);
       }
    }

    //Vertaa antaa listalle järjestyksen
    //eka - osoitin ensimmäiseen henkilo -tietueeseen
    //toka - osoitin toiseen henkilo -tietueeseen
    int Vertaa(const void* eka, const void* toka)
    {
       struct henkilo* phenk1 = (struct henkilo*)eka;
       struct henkilo* phenk2 = (struct henkilo*)toka;
       int i;
       i = stricmp(phenk1->artisti, phenk2->artisti);
       if (!i)
          i = stricmp(phenk1->levy, phenk2->levy);
       return i;
    }

    int main(void)
    {
       struct henkilo henkilo_lista[MAX_LEVYA];
       unsigned hlomaara, poistettava;
       struct henkilo* phenk;
       unsigned i, j;
       
       hlomaara = LueTiedostoMuistiin(henkilo_lista);
       if(hlomaara > (unsigned)-1)
          return 1;

       phenk = henkilo_lista;
       phenk += hlomaara; //Uuden tiedon kohdalle

       i = 0;

       while(!i) {
          char buffer[4], c;
          printf("\n\n\n\n============\nAlkuvalikko\n------------\n"
             "Valitse:\n1 Lisää luetteloon\n2 Poista luettelosta\n"
             "3 Tulosta sisältö\n4 Järjestele\n5 Muokkaa\n\n9 Lopettaa ohjelman\n"
             "------------\nValintasi:");
          switch(c = fgetc(stdin) - '0') {
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 9:
             i = c;
          }
          for(j = c + '0'; j != '\n' && j != EOF; j = fgetc(stdin));
          switch(i) {
          case 1: //Käyttäjältä uusi henkilö
             phenk = UusiHenkilo(phenk, &hlomaara);
             i = 0;
             break;
          case 2: //Poistettavana joku listalta
             TulostaSisalto(henkilo_lista, hlomaara);
             printf("\n\nAnna poistettava:");
             fgets(buffer, 4, stdin);
             poistettava = atoi(buffer);
             phenk = PoistaHenkilo(henkilo_lista, phenk, &hlomaara, poistettava);
             i = 0;
             break;
          case 3: //Tulostaa sisällön
             TulostaSisalto(henkilo_lista, hlomaara);
             i = 0;
             break;
          case 4: //Järjestelee aakkosjärjestykseen
             qsort(henkilo_lista, hlomaara, sizeof(henkilo), Vertaa);
             i = 0;
             break;
          case 5: //Muokkaa tietuetta
             MuutaTietoja(henkilo_lista, hlomaara);
             i = 0;
          }
       }

       //Listan tallennus tiedostoon
       TallennaTiedostoon(henkilo_lista, hlomaara);

       return 0;
    }

    /*
    //Rivin poistaminen muuttuvaleveyksisestä tiedostosta

    int main(void)
    {
    unsigned hlomaara;
    char rekisteri[] = "luettelo.txt";
    FILE *avaus;
    char buffer[3208], *pc;
    unsigned luettumaara;

    if ((avaus = fopen(rekisteri, "r")) != NULL) { //Jos tiedosto on siis olemassa, avataan vain lukuun
    unsigned i, j;
    luettumaara = fread(buffer, 1, 3207, avaus); //Luku
    fclose(avaus);//ja sulkeminen
    if(!luettumaara){
    printf("Tiedosto on väärässä muodossa");
    return 2;
    }
    //Etsitään luettelon alku (oletan että kyseessä on tietynmuotoinen tiedosto ;))
    for(i = luettumaara, pc = buffer;*pc != '\n';pc++, --i);
    pc++; //Koska oltiin rivin vaihdon kohdalla
    --i; //Tässä on tiedosta luettujen henkilo -tietueiden koko
    //Nyt ollaan siis ensimmäisen henkilön kohdalla. Seuraaviin pääsee hakemalla rivinvaihtoa. Muista kuitenkin pienentää i:n arvoa vastaavasti
    //Poistan malliksi ensimmäisen käyttäen siirtomenetelmää
    if(i) {
    char*pc2; //Avuksi toinen osoitin, jota käytetään hakemaan seuraava tietue
    for(pc2 = pc, j = i ; *pc2 != '\n' && j ; pc2++, --j); //Haetaan seuraavaa riviä
    pc2++; //tietueen alkuun
    if(j){ //jos tietueita ei olisi jäljellä, siirtoa ei tarvitsisi tehdä
    --j; //koska pc2:ta kasvatettiin
    memcpy(pc, pc2, j);//Kohde on siis pc, lähde pc2 ja jäljellä olevien tavujen määrä j
    pc += j;//katkaisurajan kohdalle
    }
    pc2 = pc; //pc2 on nyt ensimmäisen poistettavan merkin kohdalla
    //ja sitä määrää pitää taas viilata eli
    hlomaara = atoi(buffer); //alkuperäinen
    hlomaara--; //uusi
    pc = buffer;
    if(hlomaara >= 10){
    *pc = (hlomaara / 10) + '0'; //kymmenet merkikse
    pc[1] = (hlomaara % 10) + '0'; //alle kymmenet merkiksi
    }
    else{
    if(hlomaara == 9) //Tässä numero lyhenee
    pc++;
    *pc = hlomaara + '0'; //ja sama merkkinä
    }
    if ((avaus = fopen(rekisteri, "w")) != NULL) { //Tuhotaan tiedoston alkuperäinen sisältö
    fwrite(pc, 1, pc2 - pc, avaus); //ja kirjoitus takaisin tiedostoon
    fclose(avaus);
    }
    }
    }
    return 0;
    }*/

    Oho! Tuli aika vaikean selkoisti koodia :/ Heittää kuitenkin herjaa tuossa case 4-kohdassa:

    qsort(henkilo_lista, hlomaara, sizeof(henkilo), Vertaa); Ilmoittaa että henkilö unclared.

    Mitä muuttijia nuo pc ja pc2 ovat?

    Äänestä

  • Koodari kirjoitti:

    Oho! Tuli aika vaikean selkoisti koodia :/ Heittää kuitenkin herjaa tuossa case 4-kohdassa:

    qsort(henkilo_lista, hlomaara, sizeof(henkilo), Vertaa); Ilmoittaa että henkilö unclared.

    Mitä muuttijia nuo pc ja pc2 ovat?

    qsort(henkilo_lista, hlomaara, sizeof(struct henkilo), Vertaa);

    Ne ovat tilapäisiä muuttujia aivan kuten i,j,c,m.

    Äänestä

  • pitäisi olla kirjoitti:

    qsort(henkilo_lista, hlomaara, sizeof(struct henkilo), Vertaa);

    Ne ovat tilapäisiä muuttujia aivan kuten i,j,c,m.

    Mikäs toi viimeisen pätkän idea tuossa on, mikä on laitettu kommentiksi?

    Äänestä

  • Koodari kirjoitti:

    Mikäs toi viimeisen pätkän idea tuossa on, mikä on laitettu kommentiksi?

    Unohtui jostain vanhasta vastauksesta. Sitä et tarvitse ;)

    Äänestä

  • oleellista tuossa kirjoitti:

    Unohtui jostain vanhasta vastauksesta. Sitä et tarvitse ;)

    Kuin kauan sulla menee tuollaisen koodipätkän kirjoittamisessa?

    Onko siirtyminen c-kielestä Visual c:hen kuin iso haaste vai onko se helpompi ohjelma käyttää?

    Äänestä

  • Koodari kirjoitti:

    Kuin kauan sulla menee tuollaisen koodipätkän kirjoittamisessa?

    Onko siirtyminen c-kielestä Visual c:hen kuin iso haaste vai onko se helpompi ohjelma käyttää?

    Tuo pätkä oli jo valmiina, joten tein vain pieniä muutoksia (tietue, lajittelu, muokkaus). Aikaa meni alle puoli tuntia testailuineen.

    Visual Studion pro-versiot on huomattavasti helpompikäyttöisiä kuin muut, kun tehdään ohjelmia Windowsiin. Esim. Dev-C :n ja Express -versioon verrattuna asentelu ja aloitus on helpompaa (ei tarvitse pähkäillä mistä saisi resurssieditorin). Perus C konsolilla on monesti paljon hankalampaa kuin graafisessa käyttöliittymässä eli täytyy itse kirjoitella paljon koodia jokaista toimintoa varten. Visual Studiossa toimintoja saa graafisiin versioihin suoraan muutamalla hiiren klikauksella eli keskitytään enemmän itse ohjelman toimintaan kuin käyttöliittymän tekemiseen.

    Jos vertaa Dev-C:tä oppimisen kannalta, niin Visual C :ssa helppitiedostot on sidottu IDE:n ja koodiin. Näin ollen koodissa F1:n painaminen tuo funktion täydelliset ohjeet. Tietty ohjeet saa netistäkin, mutta siihen meneekin jo pitemmän aikaa.

    Äänestä

  • apuja ongelmaan kirjoitti:

    #include
    #include
    #include

    #define KOKO 50
    #define PITUUS 20
    #define MAX_LEVYA 500

    struct henkilo {
       char levy[KOKO];
       char artisti[KOKO];
       char vuosi[PITUUS];
       char arvosana[PITUUS];
    };

    const char rekisteri[] = "luettelo.txt";

    //TiedonKopiointi kopioi tekstin in -> out
    //out - osoitin kohteeseen, in - osoitin lähteeseen
    //koko - tiedon maksimikoko
    //Paluuarvo on
    //- joko osoitin seuraavan tiedon alkuun
    //- tai koko -kentän määräämään osoitteeseen
    char* TiedonKopiointi(char*out, char*in, unsigned koko)
    {
       char* pc, *pc2;
       unsigned j;
       memset(out, 0, koko);
       pc = in;
       pc2 = out;
       for(j = koko; j && *pc != ' ' && *pc != '\n'; --j){
          *pc2 = *pc;
          pc2++;
          pc++;
       }
       return ++pc;
    }

    //TaytaTietue täyttää tietueen yhden rivin
    //buffer - osoitin merkkijonoon, jossa on tiedostosta luettu tekstirivi
    //phenk - osoitin tietueen rivin alkuun
    //Paluuarvona osoitin seuraavaan tietueeseen
    struct henkilo* TaytaTietue(char*buffer, struct henkilo*phenk)
    {
       char* pc;
       pc = buffer;
       pc = TiedonKopiointi(phenk->levy, pc, KOKO);
       pc = TiedonKopiointi(phenk->artisti, pc, KOKO);
       pc = TiedonKopiointi(phenk->vuosi, pc, PITUUS);
       pc = TiedonKopiointi(phenk->arvosana, pc, PITUUS);
       //Tässä kohdassa voisi varmistaa, että ollaan seuraavalla rivillä
       return ++phenk;
    }

    //LueTiedostoMuistiin lukee tiedoston henkilo -tietuetaulukkoon
    //henkilo_lista - henkilo -tietuetaulukon osoite
    unsigned LueTiedostoMuistiin(struct henkilo*henkilo_lista)
    {
       char buffer[sizeof(struct henkilo)];
       FILE *tiedosto;
       int hlomaara = 0;
       struct henkilo* phenk;
       long i;
       if ((tiedosto = fopen(rekisteri, "r")) != NULL) {
          fgets(buffer, 4, tiedosto);
          hlomaara = atoi(buffer);
          if (hlomaara >= MAX_LEVYA) {
             printf("Korkeintaan %d tietuetta", MAX_LEVYA);
             fclose(tiedosto);
             return -1;
          }
          for(i = 1, phenk = henkilo_lista; i = MAX_LEVYA){
          printf("Ei voi lisätä. Maksimimäärä listalla");
          return phenk;
       }
       printf("Anna levyn nimi:");
       LueMerkkijono(phenk->levy, KOKO - 1);
       printf("Anna artisti:");
       LueMerkkijono(phenk->artisti, KOKO - 1);
       printf("Anna ilmestymisvuosi:");
       LueMerkkijono(phenk->vuosi, PITUUS - 1);
       printf("Anna arvosana:");
       LueMerkkijono(phenk->arvosana, PITUUS - 1);
       *maara = *maara + 1;
       return ++phenk;
    }

    //PoistaHenkilo poistaa henkilo -tietuetaulukosta halutun tiedon (rivin)
    //henkilo_lista - osoitin henkilo -tietuetaulukon alkuun
    //phenk - osoitin seuraavaan vapaaseen paikkaan taulukossa
    //hlomaara - osoitin tietojen määrään taulukossa
    //poistettava - poistettavan rivin numero (1 on ensimmäinen)
    //Paluuarvona osoitin seuraavaan vapaaseen tietueeseen ja määrä pienenee
    struct henkilo* PoistaHenkilo(struct henkilo* henkilo_lista, struct henkilo*phenk,
                                                 unsigned* hlomaara, unsigned poistettava)
    {
       struct henkilo *phenk1, *phenk2;
       char* pc, *pc2;
       unsigned i = *hlomaara;
       if(poistettava > i)
          return phenk;
       else if(poistettava != i){ //Onko viimeinen tieto ?
          phenk1 = henkilo_lista;
          phenk1 += (poistettava - 1); //Poistettavan kohdalle
          phenk2 = phenk1;
          phenk2++; //Ensimmäisen siirrettävän kohdalle
          //Siirrä loppuja pykälällä alkuun päin
          pc2 = (char*)(void*)phenk2;
          pc = (char*)(void*)phenk;
          memcpy(phenk1, phenk2, pc - pc2);
       }
       *hlomaara = i - 1;
       return --phenk;
    }

    //TallennaTiedostoon tallentaa henkilo -tietuetaulukon
    //phenk - osoitin ensimmäiseen tietoon tietuetaulukossa
    //maara - tietojen määrä taulukossa
    unsigned TallennaTiedostoon(struct henkilo* phenk, unsigned maara)
    {
       FILE *tiedosto;
       unsigned i;
       if ((tiedosto = fopen(rekisteri, "w")) == NULL) { //Uuden tiedoston luonti
          printf("Virhe tiedoston avaamisessa.");
          return 1;
       }
       fprintf(tiedosto, "%d\n", maara); //Kirjoitettavien määrä tiedoston alkuun
       for(i = maara; i; --i){
          fprintf(tiedosto,"%s %s %s %s\n", phenk->levy, phenk->artisti, phenk->vuosi, phenk->arvosana);
          phenk++;
       }
       fclose(tiedosto);
       printf("Tietojen tallennus onnistui\n");
       return 0;
    }

    //TulostaSisalto tulostaa tietueen sisällön
    //henkilo_lista - osoitin tietueen alkuun
    //maara - tietojen määrä taulukossa
    void TulostaSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned i = maara;
       printf("\n");
       for(i = 1 ; i levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
       }
    }

    //MuutaTietoja
    void MuutaTietoja(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned muutettava;
       char buffer[PITUUS];
       TulostaSisalto(henkilo_lista, maara);
       printf("\nAnna muutettava:");
       fgets(buffer, 4, stdin);
       muutettava = atoi(buffer);
       if(muutettava levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
          printf("\nAnna uusi arvosana:");
          LueMerkkijono(buffer, PITUUS - 1);
          memcpy(phenk->arvosana, buffer, PITUUS);
       }
    }

    //Vertaa antaa listalle järjestyksen
    //eka - osoitin ensimmäiseen henkilo -tietueeseen
    //toka - osoitin toiseen henkilo -tietueeseen
    int Vertaa(const void* eka, const void* toka)
    {
       struct henkilo* phenk1 = (struct henkilo*)eka;
       struct henkilo* phenk2 = (struct henkilo*)toka;
       int i;
       i = stricmp(phenk1->artisti, phenk2->artisti);
       if (!i)
          i = stricmp(phenk1->levy, phenk2->levy);
       return i;
    }

    int main(void)
    {
       struct henkilo henkilo_lista[MAX_LEVYA];
       unsigned hlomaara, poistettava;
       struct henkilo* phenk;
       unsigned i, j;
       
       hlomaara = LueTiedostoMuistiin(henkilo_lista);
       if(hlomaara > (unsigned)-1)
          return 1;

       phenk = henkilo_lista;
       phenk += hlomaara; //Uuden tiedon kohdalle

       i = 0;

       while(!i) {
          char buffer[4], c;
          printf("\n\n\n\n============\nAlkuvalikko\n------------\n"
             "Valitse:\n1 Lisää luetteloon\n2 Poista luettelosta\n"
             "3 Tulosta sisältö\n4 Järjestele\n5 Muokkaa\n\n9 Lopettaa ohjelman\n"
             "------------\nValintasi:");
          switch(c = fgetc(stdin) - '0') {
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 9:
             i = c;
          }
          for(j = c + '0'; j != '\n' && j != EOF; j = fgetc(stdin));
          switch(i) {
          case 1: //Käyttäjältä uusi henkilö
             phenk = UusiHenkilo(phenk, &hlomaara);
             i = 0;
             break;
          case 2: //Poistettavana joku listalta
             TulostaSisalto(henkilo_lista, hlomaara);
             printf("\n\nAnna poistettava:");
             fgets(buffer, 4, stdin);
             poistettava = atoi(buffer);
             phenk = PoistaHenkilo(henkilo_lista, phenk, &hlomaara, poistettava);
             i = 0;
             break;
          case 3: //Tulostaa sisällön
             TulostaSisalto(henkilo_lista, hlomaara);
             i = 0;
             break;
          case 4: //Järjestelee aakkosjärjestykseen
             qsort(henkilo_lista, hlomaara, sizeof(henkilo), Vertaa);
             i = 0;
             break;
          case 5: //Muokkaa tietuetta
             MuutaTietoja(henkilo_lista, hlomaara);
             i = 0;
          }
       }

       //Listan tallennus tiedostoon
       TallennaTiedostoon(henkilo_lista, hlomaara);

       return 0;
    }

    /*
    //Rivin poistaminen muuttuvaleveyksisestä tiedostosta

    int main(void)
    {
    unsigned hlomaara;
    char rekisteri[] = "luettelo.txt";
    FILE *avaus;
    char buffer[3208], *pc;
    unsigned luettumaara;

    if ((avaus = fopen(rekisteri, "r")) != NULL) { //Jos tiedosto on siis olemassa, avataan vain lukuun
    unsigned i, j;
    luettumaara = fread(buffer, 1, 3207, avaus); //Luku
    fclose(avaus);//ja sulkeminen
    if(!luettumaara){
    printf("Tiedosto on väärässä muodossa");
    return 2;
    }
    //Etsitään luettelon alku (oletan että kyseessä on tietynmuotoinen tiedosto ;))
    for(i = luettumaara, pc = buffer;*pc != '\n';pc++, --i);
    pc++; //Koska oltiin rivin vaihdon kohdalla
    --i; //Tässä on tiedosta luettujen henkilo -tietueiden koko
    //Nyt ollaan siis ensimmäisen henkilön kohdalla. Seuraaviin pääsee hakemalla rivinvaihtoa. Muista kuitenkin pienentää i:n arvoa vastaavasti
    //Poistan malliksi ensimmäisen käyttäen siirtomenetelmää
    if(i) {
    char*pc2; //Avuksi toinen osoitin, jota käytetään hakemaan seuraava tietue
    for(pc2 = pc, j = i ; *pc2 != '\n' && j ; pc2++, --j); //Haetaan seuraavaa riviä
    pc2++; //tietueen alkuun
    if(j){ //jos tietueita ei olisi jäljellä, siirtoa ei tarvitsisi tehdä
    --j; //koska pc2:ta kasvatettiin
    memcpy(pc, pc2, j);//Kohde on siis pc, lähde pc2 ja jäljellä olevien tavujen määrä j
    pc += j;//katkaisurajan kohdalle
    }
    pc2 = pc; //pc2 on nyt ensimmäisen poistettavan merkin kohdalla
    //ja sitä määrää pitää taas viilata eli
    hlomaara = atoi(buffer); //alkuperäinen
    hlomaara--; //uusi
    pc = buffer;
    if(hlomaara >= 10){
    *pc = (hlomaara / 10) + '0'; //kymmenet merkikse
    pc[1] = (hlomaara % 10) + '0'; //alle kymmenet merkiksi
    }
    else{
    if(hlomaara == 9) //Tässä numero lyhenee
    pc++;
    *pc = hlomaara + '0'; //ja sama merkkinä
    }
    if ((avaus = fopen(rekisteri, "w")) != NULL) { //Tuhotaan tiedoston alkuperäinen sisältö
    fwrite(pc, 1, pc2 - pc, avaus); //ja kirjoitus takaisin tiedostoon
    fclose(avaus);
    }
    }
    }
    return 0;
    }*/

    Jos haluan etsiä tiettyjä tietoja vaikka siten, että haluan tulostaa tietyt tiedot (esim. yhden artistin tietyn levyn tiedot tai yhden artistin kaikkien levyjen tiedot? Tarvitseeko tuo siinä tapauksessa suuriakaan muutoksia? Hakee vaan if-lauseella nuo tiedot?

    void Hae(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    printf("\nAnna artistin nimi");
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }
    /*Pause-komennolla pysaytetaan listaus*/
        system("pause");
    }

    Äänestä

  • Koodari kirjoitti:

    Jos haluan etsiä tiettyjä tietoja vaikka siten, että haluan tulostaa tietyt tiedot (esim. yhden artistin tietyn levyn tiedot tai yhden artistin kaikkien levyjen tiedot? Tarvitseeko tuo siinä tapauksessa suuriakaan muutoksia? Hakee vaan if-lauseella nuo tiedot?

    void Hae(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    printf("\nAnna artistin nimi");
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }
    /*Pause-komennolla pysaytetaan listaus*/
        system("pause");
    }

    Ei tarvitse muuta kuin tehdä tuollainen for -silmukka, jossa vertaillaan stricmp:lla tekstejä.

    Äänestä

  • juippi2 kirjoitti:

    Ei tarvitse muuta kuin tehdä tuollainen for -silmukka, jossa vertaillaan stricmp:lla tekstejä.

    Tuleeko toi sit tyyliin:

    for (lause)
    if (strcmp(lause))

    Äänestä

  • Koodari kirjoitti:

    Jos haluan etsiä tiettyjä tietoja vaikka siten, että haluan tulostaa tietyt tiedot (esim. yhden artistin tietyn levyn tiedot tai yhden artistin kaikkien levyjen tiedot? Tarvitseeko tuo siinä tapauksessa suuriakaan muutoksia? Hakee vaan if-lauseella nuo tiedot?

    void Hae(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    printf("\nAnna artistin nimi");
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }
    /*Pause-komennolla pysaytetaan listaus*/
        system("pause");
    }

    Miks tällä ei toimi. Vai ymmärsinkö väärin ton käytön?


    void EtsiSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    printf("\nAnna artistin nimi");
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }
    /*Pause-komennolla pysaytetaan listaus*/
        system("pause");
    }

    Äänestä

  • Koodari kirjoitti:

    Miks tällä ei toimi. Vai ymmärsinkö väärin ton käytön?


    void EtsiSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    printf("\nAnna artistin nimi");
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }
    /*Pause-komennolla pysaytetaan listaus*/
        system("pause");
    }

    Oletin, että olisit laittanut ne scanf:t paikoilleen eli kohdan
    printf("\nAnna levyn nimi");
    jälkeen
    LueMerkkijono(levy, KOKO - 1);
    jossa levy on:
    char levy[KOKO];
    Vastaavanlainen toisen pyynnön jälkeen.
    Käytä vertailussa mieluimmin stricmp -funktiota, jolloin tekstin koolla ei ole merkitystä.

    Äänestä

  • juippi2 kirjoitti:

    Oletin, että olisit laittanut ne scanf:t paikoilleen eli kohdan
    printf("\nAnna levyn nimi");
    jälkeen
    LueMerkkijono(levy, KOKO - 1);
    jossa levy on:
    char levy[KOKO];
    Vastaavanlainen toisen pyynnön jälkeen.
    Käytä vertailussa mieluimmin stricmp -funktiota, jolloin tekstin koolla ei ole merkitystä.

    void EtsiSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    LueMerkkijono(levy, KOKO - 1);
    char levy[KOKO];
    printf("\nAnna artistin nimi");
    LueMerkkijono(artisti, KOKO_2 - 1);
    char levy[KOKO_2];
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }    system("pause");
    }

    Äänestä

  • juippi2 kirjoitti:

    Oletin, että olisit laittanut ne scanf:t paikoilleen eli kohdan
    printf("\nAnna levyn nimi");
    jälkeen
    LueMerkkijono(levy, KOKO - 1);
    jossa levy on:
    char levy[KOKO];
    Vastaavanlainen toisen pyynnön jälkeen.
    Käytä vertailussa mieluimmin stricmp -funktiota, jolloin tekstin koolla ei ole merkitystä.

    void EtsiSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    char levy[KOKO];/*jossa levy on*/
    char artisti[KOKO_2];/*jossa artisti on*/
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    LueMerkkijono(levy, KOKO - 1);
    printf("\nAnna artistin nimi");
    LueMerkkijono(artisti, KOKO_2 - 1);
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }
    }

    Äänestä

  • Koodari kirjoitti:

    void EtsiSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2 = maara;
    printf("\n");
    printf("\nAnna levyn nimi");
    LueMerkkijono(levy, KOKO - 1);
    char levy[KOKO];
    printf("\nAnna artistin nimi");
    LueMerkkijono(artisti, KOKO_2 - 1);
    char levy[KOKO_2];
    for(muuttuja_2 = 1 ; muuttuja_2 levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }    system("pause");
    }

    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2;
    char levy[KOKO], artisti[KOKO];
    printf("\n");
    printf("\nAnna levyn nimi");
    LueMerkkijono(levy, KOKO - 1);
    printf("\nAnna artistin nimi");
    LueMerkkijono(artisti, KOKO - 1);

    .
    :
    if(!stricmp(phenk->levy, levy)){
    printf("%d. ", muuttuja_2);
    printf(phenk->levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }

    Äänestä

  • juippi2 kirjoitti:

    struct henkilo* phenk = henkilo_lista;
    unsigned muuttuja_2;
    char levy[KOKO], artisti[KOKO];
    printf("\n");
    printf("\nAnna levyn nimi");
    LueMerkkijono(levy, KOKO - 1);
    printf("\nAnna artistin nimi");
    LueMerkkijono(artisti, KOKO - 1);

    .
    :
    if(!stricmp(phenk->levy, levy)){
    printf("%d. ", muuttuja_2);
    printf(phenk->levy),printf("\t");
    printf(phenk->artisti),printf("\t");
    printf(phenk->vuosi),printf("\t");
    printf(phenk->arvosana),printf("\n");
    }

    Eli tota stricmp-komentoa voi käyttää aina if-lauseen tilalle? Kuin tuo noin käytännössä eroaa if-komennosta?

    Äänestä

  • Koodari kirjoitti:

    Eli tota stricmp-komentoa voi käyttää aina if-lauseen tilalle? Kuin tuo noin käytännössä eroaa if-komennosta?

    Ei siinä korvata if -lausetta, vaan se sisältää funktion, jossa on for ja if lause sekä tapa muuntaa merkit isoiksi/pieniksi vertailua varten.

    Äänestä

  • Koodari kirjoitti:

    Eli tota stricmp-komentoa voi käyttää aina if-lauseen tilalle? Kuin tuo noin käytännössä eroaa if-komennosta?

    stricmp(char*eka, char*toka)
    {
       while(*eka && *toka){
          if(UPPER(*eka)!=UPPER(*toka))
             break;
          eka , toka ;
       }
       if(*eka == *toka)
          return 0;
       else if(*eka > *toka)
          return 1;
       else
          return -1;
    }

    Äänestä

  • apuja ongelmaan kirjoitti:

    #include
    #include
    #include

    #define KOKO 50
    #define PITUUS 20
    #define MAX_LEVYA 500

    struct henkilo {
       char levy[KOKO];
       char artisti[KOKO];
       char vuosi[PITUUS];
       char arvosana[PITUUS];
    };

    const char rekisteri[] = "luettelo.txt";

    //TiedonKopiointi kopioi tekstin in -> out
    //out - osoitin kohteeseen, in - osoitin lähteeseen
    //koko - tiedon maksimikoko
    //Paluuarvo on
    //- joko osoitin seuraavan tiedon alkuun
    //- tai koko -kentän määräämään osoitteeseen
    char* TiedonKopiointi(char*out, char*in, unsigned koko)
    {
       char* pc, *pc2;
       unsigned j;
       memset(out, 0, koko);
       pc = in;
       pc2 = out;
       for(j = koko; j && *pc != ' ' && *pc != '\n'; --j){
          *pc2 = *pc;
          pc2++;
          pc++;
       }
       return ++pc;
    }

    //TaytaTietue täyttää tietueen yhden rivin
    //buffer - osoitin merkkijonoon, jossa on tiedostosta luettu tekstirivi
    //phenk - osoitin tietueen rivin alkuun
    //Paluuarvona osoitin seuraavaan tietueeseen
    struct henkilo* TaytaTietue(char*buffer, struct henkilo*phenk)
    {
       char* pc;
       pc = buffer;
       pc = TiedonKopiointi(phenk->levy, pc, KOKO);
       pc = TiedonKopiointi(phenk->artisti, pc, KOKO);
       pc = TiedonKopiointi(phenk->vuosi, pc, PITUUS);
       pc = TiedonKopiointi(phenk->arvosana, pc, PITUUS);
       //Tässä kohdassa voisi varmistaa, että ollaan seuraavalla rivillä
       return ++phenk;
    }

    //LueTiedostoMuistiin lukee tiedoston henkilo -tietuetaulukkoon
    //henkilo_lista - henkilo -tietuetaulukon osoite
    unsigned LueTiedostoMuistiin(struct henkilo*henkilo_lista)
    {
       char buffer[sizeof(struct henkilo)];
       FILE *tiedosto;
       int hlomaara = 0;
       struct henkilo* phenk;
       long i;
       if ((tiedosto = fopen(rekisteri, "r")) != NULL) {
          fgets(buffer, 4, tiedosto);
          hlomaara = atoi(buffer);
          if (hlomaara >= MAX_LEVYA) {
             printf("Korkeintaan %d tietuetta", MAX_LEVYA);
             fclose(tiedosto);
             return -1;
          }
          for(i = 1, phenk = henkilo_lista; i = MAX_LEVYA){
          printf("Ei voi lisätä. Maksimimäärä listalla");
          return phenk;
       }
       printf("Anna levyn nimi:");
       LueMerkkijono(phenk->levy, KOKO - 1);
       printf("Anna artisti:");
       LueMerkkijono(phenk->artisti, KOKO - 1);
       printf("Anna ilmestymisvuosi:");
       LueMerkkijono(phenk->vuosi, PITUUS - 1);
       printf("Anna arvosana:");
       LueMerkkijono(phenk->arvosana, PITUUS - 1);
       *maara = *maara + 1;
       return ++phenk;
    }

    //PoistaHenkilo poistaa henkilo -tietuetaulukosta halutun tiedon (rivin)
    //henkilo_lista - osoitin henkilo -tietuetaulukon alkuun
    //phenk - osoitin seuraavaan vapaaseen paikkaan taulukossa
    //hlomaara - osoitin tietojen määrään taulukossa
    //poistettava - poistettavan rivin numero (1 on ensimmäinen)
    //Paluuarvona osoitin seuraavaan vapaaseen tietueeseen ja määrä pienenee
    struct henkilo* PoistaHenkilo(struct henkilo* henkilo_lista, struct henkilo*phenk,
                                                 unsigned* hlomaara, unsigned poistettava)
    {
       struct henkilo *phenk1, *phenk2;
       char* pc, *pc2;
       unsigned i = *hlomaara;
       if(poistettava > i)
          return phenk;
       else if(poistettava != i){ //Onko viimeinen tieto ?
          phenk1 = henkilo_lista;
          phenk1 += (poistettava - 1); //Poistettavan kohdalle
          phenk2 = phenk1;
          phenk2++; //Ensimmäisen siirrettävän kohdalle
          //Siirrä loppuja pykälällä alkuun päin
          pc2 = (char*)(void*)phenk2;
          pc = (char*)(void*)phenk;
          memcpy(phenk1, phenk2, pc - pc2);
       }
       *hlomaara = i - 1;
       return --phenk;
    }

    //TallennaTiedostoon tallentaa henkilo -tietuetaulukon
    //phenk - osoitin ensimmäiseen tietoon tietuetaulukossa
    //maara - tietojen määrä taulukossa
    unsigned TallennaTiedostoon(struct henkilo* phenk, unsigned maara)
    {
       FILE *tiedosto;
       unsigned i;
       if ((tiedosto = fopen(rekisteri, "w")) == NULL) { //Uuden tiedoston luonti
          printf("Virhe tiedoston avaamisessa.");
          return 1;
       }
       fprintf(tiedosto, "%d\n", maara); //Kirjoitettavien määrä tiedoston alkuun
       for(i = maara; i; --i){
          fprintf(tiedosto,"%s %s %s %s\n", phenk->levy, phenk->artisti, phenk->vuosi, phenk->arvosana);
          phenk++;
       }
       fclose(tiedosto);
       printf("Tietojen tallennus onnistui\n");
       return 0;
    }

    //TulostaSisalto tulostaa tietueen sisällön
    //henkilo_lista - osoitin tietueen alkuun
    //maara - tietojen määrä taulukossa
    void TulostaSisalto(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned i = maara;
       printf("\n");
       for(i = 1 ; i levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
       }
    }

    //MuutaTietoja
    void MuutaTietoja(struct henkilo* henkilo_lista, unsigned maara)
    {
       struct henkilo* phenk = henkilo_lista;
       unsigned muutettava;
       char buffer[PITUUS];
       TulostaSisalto(henkilo_lista, maara);
       printf("\nAnna muutettava:");
       fgets(buffer, 4, stdin);
       muutettava = atoi(buffer);
       if(muutettava levy),printf("\t");
          printf(phenk->artisti),printf("\t");
          printf(phenk->vuosi),printf("\t");
          printf(phenk->arvosana),printf("\n");
          printf("\nAnna uusi arvosana:");
          LueMerkkijono(buffer, PITUUS - 1);
          memcpy(phenk->arvosana, buffer, PITUUS);
       }
    }

    //Vertaa antaa listalle järjestyksen
    //eka - osoitin ensimmäiseen henkilo -tietueeseen
    //toka - osoitin toiseen henkilo -tietueeseen
    int Vertaa(const void* eka, const void* toka)
    {
       struct henkilo* phenk1 = (struct henkilo*)eka;
       struct henkilo* phenk2 = (struct henkilo*)toka;
       int i;
       i = stricmp(phenk1->artisti, phenk2->artisti);
       if (!i)
          i = stricmp(phenk1->levy, phenk2->levy);
       return i;
    }

    int main(void)
    {
       struct henkilo henkilo_lista[MAX_LEVYA];
       unsigned hlomaara, poistettava;
       struct henkilo* phenk;
       unsigned i, j;
       
       hlomaara = LueTiedostoMuistiin(henkilo_lista);
       if(hlomaara > (unsigned)-1)
          return 1;

       phenk = henkilo_lista;
       phenk += hlomaara; //Uuden tiedon kohdalle

       i = 0;

       while(!i) {
          char buffer[4], c;
          printf("\n\n\n\n============\nAlkuvalikko\n------------\n"
             "Valitse:\n1 Lisää luetteloon\n2 Poista luettelosta\n"
             "3 Tulosta sisältö\n4 Järjestele\n5 Muokkaa\n\n9 Lopettaa ohjelman\n"
             "------------\nValintasi:");
          switch(c = fgetc(stdin) - '0') {
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 9:
             i = c;
          }
          for(j = c + '0'; j != '\n' && j != EOF; j = fgetc(stdin));
          switch(i) {
          case 1: //Käyttäjältä uusi henkilö
             phenk = UusiHenkilo(phenk, &hlomaara);
             i = 0;
             break;
          case 2: //Poistettavana joku listalta
             TulostaSisalto(henkilo_lista, hlomaara);
             printf("\n\nAnna poistettava:");
             fgets(buffer, 4, stdin);
             poistettava = atoi(buffer);
             phenk = PoistaHenkilo(henkilo_lista, phenk, &hlomaara, poistettava);
             i = 0;
             break;
          case 3: //Tulostaa sisällön
             TulostaSisalto(henkilo_lista, hlomaara);
             i = 0;
             break;
          case 4: //Järjestelee aakkosjärjestykseen
             qsort(henkilo_lista, hlomaara, sizeof(henkilo), Vertaa);
             i = 0;
             break;
          case 5: //Muokkaa tietuetta
             MuutaTietoja(henkilo_lista, hlomaara);
             i = 0;
          }
       }

       //Listan tallennus tiedostoon
       TallennaTiedostoon(henkilo_lista, hlomaara);

       return 0;
    }

    /*
    //Rivin poistaminen muuttuvaleveyksisestä tiedostosta

    int main(void)
    {
    unsigned hlomaara;
    char rekisteri[] = "luettelo.txt";
    FILE *avaus;
    char buffer[3208], *pc;
    unsigned luettumaara;

    if ((avaus = fopen(rekisteri, "r")) != NULL) { //Jos tiedosto on siis olemassa, avataan vain lukuun
    unsigned i, j;
    luettumaara = fread(buffer, 1, 3207, avaus); //Luku
    fclose(avaus);//ja sulkeminen
    if(!luettumaara){
    printf("Tiedosto on väärässä muodossa");
    return 2;
    }
    //Etsitään luettelon alku (oletan että kyseessä on tietynmuotoinen tiedosto ;))
    for(i = luettumaara, pc = buffer;*pc != '\n';pc++, --i);
    pc++; //Koska oltiin rivin vaihdon kohdalla
    --i; //Tässä on tiedosta luettujen henkilo -tietueiden koko
    //Nyt ollaan siis ensimmäisen henkilön kohdalla. Seuraaviin pääsee hakemalla rivinvaihtoa. Muista kuitenkin pienentää i:n arvoa vastaavasti
    //Poistan malliksi ensimmäisen käyttäen siirtomenetelmää
    if(i) {
    char*pc2; //Avuksi toinen osoitin, jota käytetään hakemaan seuraava tietue
    for(pc2 = pc, j = i ; *pc2 != '\n' && j ; pc2++, --j); //Haetaan seuraavaa riviä
    pc2++; //tietueen alkuun
    if(j){ //jos tietueita ei olisi jäljellä, siirtoa ei tarvitsisi tehdä
    --j; //koska pc2:ta kasvatettiin
    memcpy(pc, pc2, j);//Kohde on siis pc, lähde pc2 ja jäljellä olevien tavujen määrä j
    pc += j;//katkaisurajan kohdalle
    }
    pc2 = pc; //pc2 on nyt ensimmäisen poistettavan merkin kohdalla
    //ja sitä määrää pitää taas viilata eli
    hlomaara = atoi(buffer); //alkuperäinen
    hlomaara--; //uusi
    pc = buffer;
    if(hlomaara >= 10){
    *pc = (hlomaara / 10) + '0'; //kymmenet merkikse
    pc[1] = (hlomaara % 10) + '0'; //alle kymmenet merkiksi
    }
    else{
    if(hlomaara == 9) //Tässä numero lyhenee
    pc++;
    *pc = hlomaara + '0'; //ja sama merkkinä
    }
    if ((avaus = fopen(rekisteri, "w")) != NULL) { //Tuhotaan tiedoston alkuperäinen sisältö
    fwrite(pc, 1, pc2 - pc, avaus); //ja kirjoitus takaisin tiedostoon
    fclose(avaus);
    }
    }
    }
    return 0;
    }*/

    Huomasin tossa vian:

    struct henkilo {
    char levy[KOKO];
    char artisti[KOKO];
    char vuosi[PITUUS];
    char arvosana[PITUUS];
    };

    Toi tietuetyyppi on määritelty oikein, sitä on käytetty väärin. Eiks Joka paikassa missä
    käytät esim. tyyppiä levy_tietue pitäisi olla struct levy_tietue?

    Jos jos haluat yksisanaisen tietuetyypin, se pitäis käyttää
    typedef:n avulla, tyyliin

    typedef struct levy_tietue_t {/* kentän määrittely */}
    levy_tietue;

    Korjatkaas toi ;)

    Äänestä

Kuinkas valmiin koodin saa komentoriviparametriseksi? Osaako kukaan auttaa?
Lisäksi pitäisi tietojen poistaminen ja arvosanan muuttaminen toteuttaa siten, että kysytään poistettavan artistin ja levyn nimeä.



/*Kirjastot*/

#include
#include
#include

/*Maaritellaan annettavien tietojen koot*/

#define KOKO 21 /*KOKO:n suuruus 20+1 merkkia*/
#define KOKO_2 31 /*KOKO_2:n suuruus 30+1 merkkia*/
#define PITUUS 20 /*PITUUS:n suuruus 19+1 merkkia*/
#define MAX_LEVYA 100 /*MAKSIMI LEVYJEN MAARA 100*/

/*Maaritetaan henkilo-taulukko*/
typedef struct musalevy_t { /*typedef tekee musalevy_t ja musalevy synonyymit*/
char levy[KOKO]; /*levy-nimi maksimissaan KOKO-suuruinen*/
char artisti[KOKO_2]; /*artisti-nimi maksimissaan KOKO_2-suuruinen*/
char vuosi[PITUUS]; /*vuosi-arvo maksimissaan PITUUS-suuruinen*/
char arvosana[PITUUS]; /*arvosana-arvo maksimissaan PITUUS-suuruinen*/
}musalevy;

const char rekisteri[] = "ht0306758.txt"; /*tiedosto nimetaan talla nimella*/

/*TietojenLuku kopioi tekstin ota -> jata*/
/*jata - osoitin kohteeseen, ota - osoitin lähteeseen*/
/*koko - tiedon maksimikoko*/
/*Paluuarvo on*/
/*- joko osoitin seuraavan tiedon alkuun*/
/*- tai koko -kentän määräämään osoitteeseen*/

char* TietojenLuku(char*jata, char*ota, unsigned koko) /*tietotyyppien maarittely*/
{
char* apuri_1, *apuri_2; /*tietotyyppien maarittely*/
unsigned muuttuja_1; /*maaritellaan, etta muuttuja_1 ei ole etumerkillinen*/
memset(jata, 0, koko); /*memset:lla muutetaan jata:sta koko-->0*/
apuri_1 = ota; /*apu-muuttujat*/
apuri_2 = jata; /*apu-muuttujat*/
for(muuttuja_1 = koko; muuttuja_1 && *apuri_1 != ' ' && *apuri_1 != '\n'; --muuttuja_1){ /*silmukka joka kay lapi avun*/
*apuri_2 = *apuri_1;
apuri_2++; /* muuttujan arvo lisaantyy*/
apuri_1++; /* muuttujan arvo lisaantyy*/
}
return ++apuri_1;
}

/****************************************************************************************************/

struct musalevy_t* TietueenTaytto(char*puskuri, struct musalevy_t*phenk) /*TietueenTaytto täyttää tietueen yhden rivin*/
{ /*puskuri - osoitin merkkijonoon, jossa on tiedostosta luettu tekstirivi*/
char* apuri_1; /*phenk - osoitin tietueen rivin alkuun*/
apuri_1 = puskuri; /*Paluuarvona osoitin seuraavaan tietueeseen*/
apuri_1 = TietojenLuku(phenk->levy, apuri_1, KOKO);
apuri_1 = TietojenLuku(phenk->artisti, apuri_1, KOKO_2);
apuri_1 = TietojenLuku(phenk->vuosi, apuri_1, PITUUS);
apuri_1 = TietojenLuku(phenk->arvosana, apuri_1, PITUUS);
return ++phenk;
}

/****************************************************************************************************/

unsigned LueTiedostoMuistiin(struct musalevy_t*musalevy_t_lista) /*LueTiedostoMuistiin lukee tiedoston henkilo -tietuetaulukkoon*/
{ /*henkilo_lista - henkilo -tietuetaulukon osoite*/
char puskuri[sizeof(struct musalevy_t)]; /*määritellään puskuri ja sen koostumus*/
FILE *tiedosto; /*kerrotaan tiedoston nimi*/
int hlomaara = 0; /*alustetaan arvo 0:ksi*/
struct musalevy_t* phenk; /*rakenteinen tietotyyppi*/
long muuttuja_2; /*muuttuja_2 tarkennetaan pitkäksi tietotyyppimuuttujaksi*/
if ((tiedosto = fopen(rekisteri, "r")) != NULL) { /*tiedostosta lukeminen*/
fgets(puskuri, 4, tiedosto); /*tiedosto luetaan merkki kerrallaan*/
hlomaara = atoi(puskuri); /*atoi palauttaa merkkijonon vastineen kokonaislukuna*/
if (hlomaara >= MAX_LEVYA) { /*if-lauseella toteutettu ehto levyjen määrästä*/
printf("Korkeintaan %d tietuetta", MAX_LEVYA);
fclose(tiedosto); /*suljetaan tiedosto*/
return -1; /*palataan ohjelmassa taaksepäin*/
}
for(muuttuja_2 = 1, phenk = musalevy_t_lista; muuttuja_2 = MAX_LEVYA){ /*ilmoitukset, jos levymäärä ylittää maksimin*/
printf("Levyjen maksimimaara on ylittynyt. Et valitettavasti voi lisata enaa levyja.\n");
printf("Ohje: jos haluat lisata levyja, poista tarpeettomat levyt tiedostosta.\n");
getchar();
return phenk;
}
printf("Anna levyn nimi: ");
LueMerkkijono(phenk->levy, KOKO - 1); /*Luetaan muistiin, kenttiin viittaaminen tehty nuolioperaatiolla*/
printf("Anna artistin nimi: ");
LueMerkkijono(phenk->artisti, KOKO_2 - 1); /*Luetaan muistiin, kenttiin viittaaminen tehty nuolioperaatiolla*/
printf("Anna levyn ilmestymisvuosi: ");
LueMerkkijono(phenk->vuosi, PITUUS - 1); /*Luetaan muistiin, kenttiin viittaaminen tehty nuolioperaatiolla*/
printf("Anna levyn arvosana (1-10): ");
LueMerkkijono(phenk->arvosana, PITUUS - 1); /*Luetaan muistiin, kenttiin viittaaminen tehty nuolioperaatiolla*/
*maara = *maara + 1;
return ++phenk;
}

/****************************************************************************************************/

struct musalevy_t* Poistamusalevy_t(struct musalevy_t* musalevy_t_lista, struct musalevy_t*phenk, unsigned* hlomaara, unsigned poistettava)
{ /*Poistamusalevy_t poistaa musalevy_t -tietuetaulukosta halutun tiedon (rivin)*/
/*musalevy_t_lista - osoitin musalevy_t -tietuetaulukon alkuun*/
struct musalevy_t *phenk1, *phenk2; /*phenk - osoitin seuraavaan vapaaseen paikkaan taulukossa*/
char* apuri_1, *apuri_2; /*hlomaara - osoitin tietojen määrään taulukossa*/
unsigned muuttuja_2 = *hlomaara; /*poistettava - poistettavan rivin numero (1 on ensimmäinen)*/
if(poistettava > muuttuja_2) /*Paluuarvona osoitin seuraavaan vapaaseen tietueeseen ja määrä pienenee*/
return phenk;
else if(poistettava != muuttuja_2){ /*Tassa kohtaa tarkastetaan onko viimeinen tieto*/
phenk1 = musalevy_t_lista;
phenk1 += (poistettava - 1); /*Tiedot poistettavan kohdalle*/
phenk2 = phenk1;
phenk2++; /* Tiedot ensimmäisen siirrettävän kohdalle*/

/*Siiretään loppuja yhdellä alkuun päin*/

apuri_2 = (char*)(void*)phenk2; /*määritellään apumuuttujat alempaa funktiota varten*/
apuri_1 = (char*)(void*)phenk; /*määritellään apumuuttujat alempaa funktiota varten*/
memcpy(phenk1, phenk2, apuri_1 - apuri_2); /*Funktio kopioi apuri_1-apuri_2:n...*/
} /*... osoitteesta phenk2 osoitteeseen phenk1 ja palauttaa osoitteen phenk1*/
*hlomaara = muuttuja_2 - 1;
return --phenk; /*palataan taaksepäin*/
}

/****************************************************************************************************/

unsigned TallennaTiedostoon(struct musalevy_t* phenk, unsigned maara) /*TallennaTiedostoon tallentaa musalevy_t -tietuetaulukon*/
{ /*phenk - osoitin ensimmäiseen tietoon tietuetaulukossa*/
FILE *tiedosto; /*maara - tietojen määrä taulukossa*/
unsigned muuttuja_2; /*muuttuja_2 on etupäätteetön*/
char valinta; /*määritellään muuttuja valinta char-tyyppiseksi*/
if ((tiedosto = fopen(rekisteri, "w")) == NULL) { /*jos avaus epäonnistuu, siitä ilmoitus virhe-tekstillä*/
printf("Virhe tiedoston avaamisessa."); /*virheilmoitus avauksesta*/
return 1; /*palataan pois*/
}

fprintf(tiedosto, "%d\n", maara); /*Kirjoitettavien määrä tiedoston alkuun*/
for(muuttuja_2 = maara; muuttuja_2; --muuttuja_2){ /*silmukka toteuttaa tietojen kierron*/
fprintf(tiedosto,"%s %s %s %s\n", phenk->levy, phenk->artisti, phenk->vuosi, phenk->arvosana); /*Luetaan tiedot muistiin*/
phenk++;
}

fclose(tiedosto); /*suljetaan tiedosto*/
printf("Tiedot tallennettu. Poistutaan ohjelmasta enteria painamalla.\n"); /*poistuminen ohjelmasta*/
getchar(); /*yksi enter-painaminen vaaditaan*/

return 0; /*ohjelma suljetaan*/
}

/****************************************************************************************************/

void TulostaSisalto(struct musalevy_t* musalevy_t_lista, unsigned maara) /*TulostaSisalto tulostaa tietueen sisällon*/
{ /*musalevy_t_lista - osoitin tietueen alkuun*/
system("cls");      /*tyhjennetaan ruutu*/ /*maara - tietojen maara taulukossa*/
printf("\nLevyn nimi - Artistin nimi - Levyn julkaisuvuosi - Levyn arvosana\n"); /*luettelon lukemisen avuksi printataan lukuohje*/
struct musalevy_t* phenk = musalevy_t_lista; /*maaritellaan phenk ja listatietueet*/
unsigned muuttuja_2 = maara; /*muuttuja_2 = maara*/
printf("\n"); /*printataan tyhja valiin*/
for(muuttuja_2 = 1 ; muuttuja_2 levy),printf(" - "); /*tulostetaan levyn nimi ja valiviiva*/
printf(phenk->artisti),printf(" - "); /*tulostetaan artistin nimi ja valiviiva*/
printf(phenk->vuosi),printf(" - "); /*tulostetaan levyn julkaisuvuosi ja valiviiva*/
printf(phenk->arvosana),printf("\n"); /*tulostetaan levyn arvosana ja valiviiva*/
}
system("pause"); /*Pause-komennolla pysaytetaan listaus*/
}

/****************************************************************************************************/

/*ETSI-TOIMINTO*/
/*EtsiSisalto tulostaa tietueen sisällön*/
/*musalevy_t_lista - osoitin tietueen alkuun*/
/*maara - tietojen määrä taulukossa*/
void EtsiSisalto(struct musalevy_t* musalevy_t_lista, unsigned maara) /*Etsi-toiminto palauttaa ainoastaan arvoja*/
{
system("cls"); /*tyhjennetaan ruutu*/
struct musalevy_t* phenk = musalevy_t_lista; /*maaritellaan taulukko*/
unsigned muuttuja_2; /*kerrotaan, etta muuttuja_2 on etumerkiton*/
char levy[KOKO]; /*maaritellaan levyn ja artistin nimen pituudet*/
char artisti[KOKO_2];
printf("\n"); /*printataan tyhja valiin*/
printf("Anna levyn nimi: "); /*Kysytaan levyn nimea*/
LueMerkkijono(levy, KOKO); /*Luetaan annettu nimi */
printf("Anna artistin nimi: "); /*Kysytaan levyn nimea*/
LueMerkkijono(artisti, KOKO_2); /*Luetaan annettu nimi */
printf("\nSeuraavat tiedot loytyivat: \n");
for(muuttuja_2 = 1 ; muuttuja_2 levy, levy) || !strcmp(phenk->artisti, artisti)){ /*strcmp vertailee, loytyyko jo annetuista tiedoista tietoja, jotka syotetaan...*/
printf("\nLevyn nimi - Artistin nimi - Levyn julkaisuvuosi - Levyn arvosana\n"); /*...strcmp sisältää for- ja if-lauseet*/
printf("\n");
printf(phenk->levy),printf(" - "); /*jos loytyy --> printataan levyn nimi*/
printf(phenk->artisti),printf(" - "); /*jos loytyy --> printataan artistin nimi*/
printf(phenk->vuosi),printf(" - "); /*jos loytyy --> printataan levyn julkaisuvuosi*/
printf(phenk->arvosana),printf("\n"); /*jos loytyy --> printataan levyn arvosana*/
}
}
printf("\n");
    system("pause"); /*Pause-komennolla pysaytetaan listaus*/
}
/****************************************************************************************************/

/*ARVOSANAN MUUTTAMINEN*/

void MuutaTietoja(struct musalevy_t* musalevy_t_lista, unsigned maara)
{
system("cls"); /*tyhjennetaan ruutu*/
struct musalevy_t* phenk = musalevy_t_lista; /*maaritellaan taulukko*/
unsigned muutettava; /*kerrotaan, etta muuttuja on etumerkiton*/
char puskuri[PITUUS]; /*puskuriille annetaan pituus ehto*/
TulostaSisalto(musalevy_t_lista, maara);
printf("\nAnna muutettavan arvosanan levyn numero: ");
fgets(puskuri, 4, stdin);
muutettava = atoi(puskuri);
if(muutettava levy),printf("\t"); /*levy-tiedot tulostetaan*/
printf(phenk->artisti),printf("\t"); /*artisti-tiedot tulostetaan*/
printf(phenk->vuosi),printf("\t"); /*julkaisuvuosi-tiedot tulostetaan*/
printf(phenk->arvosana),printf("\n"); /*arvosana-tiedot tulostetaan*/
printf("\nAnna uusi arvosana: ");
LueMerkkijono(puskuri, PITUUS - 1); /*lopuksi luetaan uusi merkkijono muistiin*/
memcpy(phenk->arvosana, puskuri, PITUUS); /*tallennetaan muistiin*/
}
else
printf("\nTietoja ei loytynyt, palataan automaattisesti takaisin valikkoon.");
getchar(); /*yksi enter-painaminen vaaditaan*/
}

/*Vertaa antaa listalle järjestyksen*/
/*eka - osoitin ensimmäiseen musalevy_t -tietueeseen*/
int Vertaa(const void* eka, const void* toka) /*toka - osoitin toiseen musalevy_t -tietueeseen*/
{ /*Maaritellaan Vertaa-toiminnon muuttujat*/
struct musalevy_t* phenk1 = (struct musalevy_t*)eka; /*määritellään tietue */
struct musalevy_t* phenk2 = (struct musalevy_t*)toka; /*määritellään tietue */
int muuttuja_2; /*määritellään muuttuja_2:n tietotyypiksi int*/
muuttuja_2 = strcmp(phenk1->artisti, phenk2->artisti); /*strcmp-komennolla vertaillan phenk1:stä ja phenk2:sta*/
if (!muuttuja_2) /*strcmp-komennolla vertaillan phenk1:stä ja phenk2:sta*/
muuttuja_2 = strcmp(phenk1->levy, phenk2->levy);
return muuttuja_2; /*Poistutaan toiminnosta*/
}

/****************************************************************************************************/

/*PAAOHJELMA*/

int main(void)
{
struct musalevy_t musalevy_t_lista[MAX_LEVYA]; /*Määritellään tietotyyppi*/
unsigned hlomaara, poistettava; /*etuliitteettömät*/
struct musalevy_t* phenk; /*määritellään rakenteinen tietotyyppi*/
unsigned muuttuja_2, muuttuja_1; /*etuliitteettömät*/

hlomaara = LueTiedostoMuistiin(musalevy_t_lista);
if(hlomaara > (unsigned)-1)
return 1;

phenk = musalevy_t_lista; /*phenk:n alustus*/
phenk += hlomaara; /*Uuden tiedon kohdalle*/

muuttuja_2 = 0;
while(!muuttuja_2) { /*Toiminnon valinta kohta while-toiminnolla*/
char puskuri[4], c;
system("cls");      /*tyhjennetaan ruutu*/
printf("============\nAlkuvalikko\n============\n");
printf("\nValitse toiminto:\n");
printf("\n1 Lisaa tietoja\n");
printf("2 Poista tietoja\n");
printf("3 Tulosta tiedot\n");
printf("4 Etsi tiedot\n");
printf("5 Lajittele tiedot aakkosjarjestykseen\n");
printf("6 Muokkaa annetun levyn arvosanaa\n");
printf("7 Poistutaan ohjelmasta\n");
printf("\n------------\nValintasi:\n");


switch(c = fgetc(stdin) - '0') { /*Valinta case-periaattella*/
case 1: /*valinta 1*/
case 2: /*valinta 2*/
case 3: /*valinta 3*/
case 4: /*valinta 4*/
case 5: /*valinta 5*/
case 6: /*valinta 6*/
case 7: /*valinta 7*/
muuttuja_2 = c;
}

for(muuttuja_1 = c + '0'; muuttuja_1 != '\n' && muuttuja_1 != EOF; muuttuja_1 = fgetc(stdin)); /*silmukka käy tiedot läpi*/
switch(muuttuja_2) {

case 1: /*tapaus 1 - Käyttäjältä uusi henkilö*/
phenk = Uusimusalevy_t(phenk, &hlomaara);
muuttuja_2 = 0;
break;

case 2: /*tapaus 2 - Poistettavana joku listalta*/
TulostaSisalto(musalevy_t_lista, hlomaara);
printf("\n\nAnna poistettava:");
fgets(puskuri, 4, stdin);
poistettava = atoi(puskuri);
phenk = Poistamusalevy_t(musalevy_t_lista, phenk, &hlomaara, poistettava);
muuttuja_2 = 0;/*alustus*/
break;

case 3: /*tapaus 3 - Tulostaa sisällön*/
TulostaSisalto(musalevy_t_lista, hlomaara);
muuttuja_2 = 0; /*alustus*/
break;

case 4: /*tapaus 4 - Etsi tietoja*/
EtsiSisalto(musalevy_t_lista, hlomaara);
muuttuja_2 = 0;/*alustus*/
break;

case 5: /*tapaus 5 - Järjestelee aakkosjärjestykseen*/
qsort(musalevy_t_lista, hlomaara, sizeof(struct musalevy_t), Vertaa); /*järjestää tilapäiset muuttujat*/
muuttuja_2 = 0; /*alustus*/
system("cls"); /*tyhjennetaan ruutu*/
printf("Tiedot jarjestelty aakkosjarjestykseen, paina enter jatkaaksesi.");
getchar(); /*yksi enter-painaminen vaaditaan*/
break;

case 6: /*tapaus 6 - Muokkaa arvosanaa*/
MuutaTietoja(musalevy_t_lista, hlomaara);
muuttuja_2 = 0;/*alustus*/
}
}

TallennaTiedostoon(musalevy_t_lista, hlomaara); /*Listan tallennus tiedostoon*/
return 0; /*Poistutaan ohjelmasta*/
}

Äänestä
  • Osaako joku asiantuntija sanoa, onko tuo ohjelma nyt oikeaoppisesti tehty?


    #include
    #include

    /*Maaritetaan levytietokanta-taulukko*/

    struct levytietokanta
    {
       char artisti[51];
       char arkisto[51];
       int vuosi;
       int arvosana;
    };

    #define MAKSIMI 100


    /* Ohjelma alkaa...*/


    int tiedostoluku(char *levytietokantaNimi, struct levytietokanta arkisto[]){
    int apuri;
    FILE *tiedosto;


    int tulosta(struct levytietokanta arkisto[]);
    int etsi(struct levytietokanta arkisto[]);
    int tietojenlisays(struct levytietokanta arkisto[]);
    int arvosanamuutos(struct levytietokanta arkisto[]);
    int tietopoistaminen(struct levytietokanta arkisto[]);
    int tietovertailu(struct levytietokanta arkistolevytietokanta1, struct levytietokanta arkistolevytietokanta2);
    int tietojarjestely(struct levytietokanta arkisto[]);
    int tietotallennus(char *levytietokanta_nimi, struct levytietokanta arkisto[]);

    /* Avataan tiedosto ja tutkitaan onnistuiko */
    /* if((lista =fopen("luettelo.txt", "r")) == NULL) */
    if ((tiedosto=fopen(levytietokantaNimi,"r")) == NULL){
    printf("Tiedoston avaus epaonnistui\n");
    return 0; }

    else {
    apuri = 0;
    char artisti2[51];
    char arkisto2[51];
    int vuosi2;
    int arvosana2;
    while(fscanf(tiedosto, "%s %s %d %d", &artisti2, &arkisto2, &vuosi2, &arvosana2) != EOF){
    strcpy(arkisto[apuri].artisti, artisti2);
    strcpy(arkisto[apuri].arkisto, arkisto2);
    arkisto[apuri].vuosi = vuosi2;
    arkisto[apuri].arvosana = arvosana2;
    apuri = apuri+1;}
    }
    /* Suljetaan tiedosto*/
    fclose(tiedosto);
    return 1;
    }


    /* Näytetään menu*/
    int menu(struct levytietokanta arkisto[]) {
    int valinta;

    valinta = 0;
    while (valinta != 7) {
    printf("\n");
    printf("============\nAlkuvalikko\n============\n");
    printf("1 = Tulosta tiedot\n");
    printf("2 = Etsi tiedot\n");
    printf("3 = Lisaa tietoja\n");
    printf("4 = Muokkaa annetun levyn arvosanaa\n");
    printf("5 = Poista tietoja\n");
    printf("6 = Lajittele tiedot aakkosjarjestykseen\n");
    printf("7 = Poistutaan ohjelmasta\n\n");
    printf("\n------------\nValintasi: ");
             scanf("%d", &valinta);

       printf("valinta = %i\n", valinta);
       if (valinta == 1){
          tulosta(arkisto);}
          
       else if (valinta == 2){
          etsi(arkisto);
          }
          
       else if (valinta == 3){
          tietojenlisays(arkisto);
    }
          
       else if (valinta == 4){
          arvosanamuutos(arkisto);
    }
          
       else if (valinta == 5){
          tietopoistaminen(arkisto);
    }
          
       else if (valinta == 6){
          tietojarjestely(arkisto);
    }
          
       else if (valinta == 7){
    }
       
       else
          valinta = 0; }/*jos valinta on 7 ohjelma tulee tähän ja tallennetaan muistiin luettu tiedosto muutoksineen takaisin arkistolle*/
    return 0;}


    /* tietotallennus */
    int tietotallennus(char *levytietokanta_nimi, struct levytietokanta arkisto[]){
    int apuri;
    FILE *tiedosto;

    /* Avataan tiedosto ja tutkitaan onnistuiko */
    if ((tiedosto=fopen(levytietokanta_nimi, "w")) == NULL){
    printf("Tiedoston avaus epaonnistui\n");
    return 0;
    }
    else {
    for (apuri = 0;apuri < MAKSIMI;apuri++){
    if (arkisto[apuri].arvosana != 0)
    fprintf(tiedosto, "%s %s %d %d\n", arkisto[apuri].artisti, arkisto[apuri].arkisto, arkisto[apuri].vuosi, arkisto[apuri].arvosana);
    }
    }
    fclose(tiedosto);
    return 0;
    }


    /* lisäystä */
    int tietojenlisays(struct levytietokanta arkisto[]) {
    char artisti2[51];
    char arkisto2[51];
    int vuosi2;
    int arvosana2;
    int apuri;
    int lisaysindeksi;

    printf("Anna arkiston tekija\n");
    scanf("%s", &artisti2);

    printf("Anna arkiston nimi\n");
    scanf("%s", &arkisto2);

    printf("Anna arkiston julkaisuvuosi\n");
    scanf("%d", &vuosi2);

    arvosana2 = 0;
    do {
    printf("Anna arkiston arvosana (1-10)\n");
    scanf("%d", &arvosana2);
    }
    while (arvosana2 10);
    apuri = 0;
    lisaysindeksi = MAKSIMI;
       while (apuri < MAKSIMI && lisaysindeksi == MAKSIMI) {
        if (arkisto[apuri].arvosana == 0)
          lisaysindeksi = apuri;
       else
       apuri = apuri +1;
       }
       
        if (lisaysindeksi == MAKSIMI) {
          printf("Tietokanta on taynna\n");
          return 1;
          }
          else {
    strcpy(arkisto[lisaysindeksi].artisti, artisti2);
    strcpy(arkisto[lisaysindeksi].arkisto, arkisto2);
    arkisto[lisaysindeksi].vuosi = vuosi2;
    arkisto[lisaysindeksi].arvosana = arvosana2;
          }
       return 0;
    }


    /* muutosta */
    int arvosanamuutos(struct levytietokanta arkisto[]) {
       char artistihakuehto[80];
       char arkistohakuehto[80];
       printf("Anna artisti jonka arvosanaa haluat muuttaa : ");
       scanf("%s", artistihakuehto);
       printf("Anna artistin %s arkisto jonka arvosanaa haluat muuttaa : ", artistihakuehto);
       scanf("%s", arkistohakuehto);
       int apuri;
       int muutettu;
       muutettu = 0;
    for (apuri = 0;apuri < MAKSIMI;apuri++) {
    if (arkisto[apuri].arvosana != 0)
          if (strcmp(artistihakuehto, arkisto[apuri].artisti) == 0 && strcmp(arkistohakuehto, arkisto[apuri].arkisto) == 0) {
             int arvosana2;
             arvosana2 = 0;
             do {
                printf("Anna arkiston uusi arvosana (1-10)\n");
                scanf("%d", &arvosana2);
                }
    while (arvosana2 10);
                arkisto[apuri].arvosana = arvosana2;
                muutettu = 1;
             }
    }
    if (muutettu != 1)
    printf("arkistoa ei loydy tietokannasta\n");

    else
    printf("arkiston arvosana muutettu\n");

    return 0;
    }


    /* poistoa */
    int tietopoistaminen(struct levytietokanta arkisto[])
    {
       char artistihakuehto[80];
       char arkistohakuehto[80];
       printf("Anna artisti jonka arkiston haluat tietopoistaminena : ");
       scanf("%s", artistihakuehto);
       printf("Anna artistin %s arkisto jonka haluat tietopoistaminena : ", artistihakuehto);
       scanf("%s", arkistohakuehto);
       int apuri;
       int poistettu;
       poistettu = 0;
    for (apuri = 0;apuri < MAKSIMI;apuri++) {
    if (arkisto[apuri].arvosana != 0)
          if (strcmp(artistihakuehto, arkisto[apuri].artisti) == 0 && strcmp(arkistohakuehto, arkisto[apuri].arkisto) == 0) {
          arkisto[apuri].arvosana = 0;
          poistettu = 1;
          }
    }
        if (poistettu != 1)
             printf("arkistoa ei loydy tietokannasta\n");
             
          else
             printf("arkisto poistettu\n");
          return 0;
    }

    int tietovertailu(struct levytietokanta arkistolevytietokanta1, struct levytietokanta arkistolevytietokanta2) {
       /*poistettu on aina suurempi */
       if (arkistolevytietokanta1.arvosana == 0)
       return 1;

       if (strcmp(arkistolevytietokanta1.artisti, arkistolevytietokanta2.artisti) < 0)
       return -1;
       if (strcmp(arkistolevytietokanta1.artisti, arkistolevytietokanta2.artisti) > 0)
       return 1;
       /* samat ovat */
       if (strcmp(arkistolevytietokanta1.arkisto, arkistolevytietokanta2.arkisto) < 0)
       return -1;
       if (strcmp(arkistolevytietokanta1.arkisto, arkistolevytietokanta2.arkisto) > 0)
       return 1;
       return 0;
       
    }

    /* järjestä */
    int tietojarjestely(struct levytietokanta arkisto[]) {
    int apuri1;
    int apuri2;
    for (apuri1 = 0;apuri1

    Äänestä

Kommentoi aloitusta


Koodari kirjoitti:

Koodiin pitäisi lisätä lajittelu joka lajittelee levyt aakkosjärjestykseen, ensin levyn nimen mukaan, ja saman artistin levyt levyn nimen mukaan.

Vielä pitäisi päästä muuttamaan arvosanaa erikseen jälkikäteen.

Olen tähän saakka saanut tehtyä seuraavanlaisen vedoksen. Osaisiko ja viitsisikö joku auttaa noiden parin toiminnon kanssa?

#include
#include
#include
#include

/*Maaritellaan kaytettavien kenttien koot*/
#define KOKO 50
#define PITUUS 20
#define MAX 500
/*Esitellaan funktio*/
void valikko();
void lisaa();
void selaa();
void etsi();
void poista();
void muuta();
void jarjestele();
void poistu();
char tietue_koko[MAX];
/*Muuttujat*/
struct tietokanta
{
   char levy [KOKO] ;
   char artisti [KOKO] ;
   char vuosi [PITUUS];
   char arvosana [PITUUS];
   char Kohde[KOKO];

} tietokanta;

/*Kaytettavat tietuenimet*/
FILE *Tiedot;
FILE *temppi;

/****************************************************************************************************/

/*PAAOHJELMA*/
int main(void)
{      
   int valinta=0;
   
      /*tyhjennetaan ruutu*/
      system("cls");
      
      /*paavalikko*/
      valikko();
      printf("Valitse toiminto: ");
      scanf("%i",&valinta);
      fflush(stdin);
      
      /*valinta toteutettu case-periaatteella*/
   switch (valinta)
   {   
         case 1:
            {
               system("cls");
               selaa();
            break;
            }

         case 2:
            {
               system("cls");
               lisaa();
            break;
            }
         
         case 3:
            {   system("cls");
               etsi();
            break;
            }

         case 4:
            {   system("cls");
               poista();
            break;
            }
            
         case 5:
            {   system("cls");
               muuta();
            break;
            }

         case 6:
            {   system("cls");
               jarjestele();
            break;
            }

       case 7:
          { system("cls");
            poistu();
         break;
         }
      default:
         {
            printf("Valitse toiminto ainoastaan 1-7 valilta\n"); system("pause");
            system("cls");
         }
   }
}
/******************************************************************************************************/

/*LISTAUS-KOHTA*/
void selaa()
{
      char valinta3;

/*Avataan tiedosto*/
      Tiedot = fopen("Tiedot.txt","a ");
      do
      {
         fgets(tietue_koko,MAX,Tiedot);
         printf("%s\n",tietue_koko);

      }while(!feof(Tiedot));

      /*Pause-komennolla stopataan listaus*/
      system("pause");
      /*Suljetaan tallennus*/
         fclose(Tiedot);
         main();
}
/******************************************************************************************************/

/*TALLENNUS-TOIMINTO*/
void lisaa()
{
      char valinta2;

      /*Avataan tiedosto, ja jos sita ei ole, luodaan se*/
         Tiedot = fopen("Tiedot.txt","a ");

         printf("Anna levyn nimi\n");

         scanf("%s",tietokanta.levy);
         
         printf("Anna artistin nimi\n");

         scanf("%s",tietokanta.artisti);
         
         printf("Anna arvosana\n");

         scanf("%s",tietokanta.arvosana);
         
         printf("Anna julkaisuvuosi\n");

         scanf("%s",tietokanta.vuosi);
         
         /*Tulostetaan tiedostoon (Records.txt) */
         fprintf(Tiedot,"%s %s %s %s \n",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);

         /*Suljetaan tallenna-toiminto*/
         fclose(Tiedot);

         main();
}
/****************************************************************************************************************/

/*PAAVALIKKO*/
void valikko()
{
   /*Valittavat toiminnot*/
      printf("Osoitekirja\n");
      printf("\n");
      printf("Valitse toiminto (1-7)\n");
      printf("\n");
      printf("1=Selaa tietoja\n");
      printf("2=Lisaa tietoja\n");
      printf("3=Etsi tietoja\n");
      printf("4=Poista tietoja\n");
      printf("5=Muuta arvosanaa\n");
      printf("6=Jarjestele tiedot aakkosjarjestykseen\n");
      printf("7=Poistu ohjelmasta\n");
      printf("\n");
}
/***********************************************************************************************/

/*ETSI-TOIMINTO*/
void etsi()
{
   /*Maaritellaan kohteen koko*/
char Kohde[MAX];
   //
   int Found=0;
   if((Tiedot=fopen("Tiedot.txt","r"))==NULL)
   
            printf("Ei tietoja!\n\n");
   
                  else
                  {
                     system("cls");
                     printf("\n\n");
                     printf("Etsi-valikko");
                     printf("\n\n");
                     printf("Valitse etsittava nimi:");
                     /*Otetaan kohde*/
                     scanf("%s",Kohde);
                              while(!feof(Tiedot)&& Found==0)
                                    {
                                       fscanf(Tiedot,"%s %s %s %s ",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);
                                       if(strcmp(Kohde,tietokanta.levy)==0)
                                       Found=1;
                                    }
                                       if(Found)
                                       {
                                          printf(".......tieto loytyi\n");
                                          system("pause");
                                          system("cls");
                                          printf("1 tieto loytyi : \n\n\n");
                                          printf("Levyn nimi: %s\n",tietokanta.levy);
                                          printf("Artistin nimi: %s\n",tietokanta.artisti);
                                          printf("Arvosana: %s\n",tietokanta.arvosana);
                                          printf("Julkaisuvuosi: %s\n",tietokanta.vuosi);
                                          system("pause");

                                       }   
                                       else if(!Found)
                                       {
                                          printf("Valitettavasti tietoja ei loytynyt\n");
                                          system("pause");
                                       }
                                          fclose(Tiedot);
          main();
}
}
/*************************************************************************************************/

/*MUUTA ARVOSANAA-KOHTA*/
   void muuta()
   {
                     printf("Poistutaan ohjelmasta }n");
   }
/***************************************************************************************************/

/*JARJESTELU-TOIMINTO*/
   void jarjestele()
   {
                     printf("Poistutaan ohjelmasta }n");
   }
/*************************************************************************************************/

/*OHJELMASTA POISTUMINEN*/
   void poistu()
   {
                     printf("Poistutaan ohjelmasta }n");
   }
/***************************************************************************************************/

/*TIETOJEN POISTAMINEN*/
   void poista()
{
   /*kohteen koko maaritelty */
char Kohde[MAX];
   int Found=0;
      system("cls");

   temppi=fopen("temppi.txt","w");
   if((Tiedot=fopen("Tiedot.txt","r"))==NULL)
      printf("Ei tietoja!\n\n");
   
               else{
                     printf("\n\n");
                     printf("Poista tietoja-valikko\n");
                     printf("\n\n");
                     printf("Anna poistettava nimi: ");
                     fflush(stdin);
                     gets(Kohde);
         while(!feof(Tiedot))
         {
         fscanf(Tiedot,"%s %s %s %s ",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);
         if(feof(Tiedot))
         break;
      if(strcmp(Kohde,tietokanta.levy)!=0)
         
         fprintf(temppi,"%s %s %s %s \n",tietokanta.levy,tietokanta.artisti,tietokanta.arvosana,tietokanta.vuosi);
                  else {
      
                        Found=1;
                     printf(".......tieto loytyi\n");
                     system("pause");
                     printf("Levyn nimi:%s\n",tietokanta.levy);
                     printf("Artistin nimi:%s\n",tietokanta.artisti);
                     printf("Arvosana: %s\n",tietokanta.arvosana);
                     printf("Julkaisuvuosi: %s\n",tietokanta.vuosi);
                     fflush(stdin);
                     system("pause");
                     }
                     }
         if (!Found)
         {
         printf("Tietoja ei loytynyt\n");/*Ilmoitus, jos tietoja ei loytynyt*/
         }
      printf("Tiedot poistettu\n");
      
      fclose(Tiedot);
      fclose(temppi);
      remove("Tiedot.txt");
      
      rename("temppi.txt","Tiedot.txt");
         main();
   }
   }

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu