Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα σας,

 

 

Έχω ένα δυαδικό αρχείο και μέσο της παρακάτω δομής εχω καταχωρίσει το όνομα και τον βαθμό του κάθε παίκτη.Όταν ο παίκτης δίνει ξανά το όνομα του,το ψάχνω στο αρχείο και του εμφανίζω τους βαθμούς του.

Όταν τελειώσει το παιχνίδι οι βαθμοί του θα έχουν αλλάξει.

 

>
struct player
{
      char onoma[30];
      int vathmos;
      
};

 

Το πρόβλημα μου είναι: πως θα αλλάξω τους παλιούς βαθμούς που είχε ο παίκτης στο αρχείο με τους καινούργιους?

 

 

Παράδειγμα ένας νέος παικτης δίνει το όνομα του kostas και στο αρχείο καταχωρήτε το όνομα "kostas" με βαθμούς 0.

 

 

 

Όταν τελειώσει το παιχνίδι οι βαθμοί του είναι 25.Πώς μπορώ να κάνω το 0 25;

 

 

Ευχαριστώ για όποια βοήθεια.

Δημοσ.

Αφού φαντάζομαι ότι γράφεις την αρχική καταχώρηση με fprintf, ο τρόπος να τη διαβάσεις πίσω στη μνήμη (αν δεν το έχεις κάνει ήδη) είναι η fscanf.

 

Απο κει και πέρα, η δουλειά θα γίνει σε κάποιο loop ως εξής:

 

  • σημειώνεις τον τρέχοντα file pointer με ftell()
  • διαβάζεις record με fscanf
  • αν το record δεν είναι αυτό που ψάχνεις, loop
  • αν είναι, τότε αλλάξεις το score στη μεταβλητή που διάβασε μόλις τώρα η fscanf, κάνεις fseek στην τελευταία τιμή που σημείωσες από την ftell και ξανά fprintf, γράφοντας έτσι την καινούρια τιμή πάνω από την παλιά

 

Φυσικά θα πρέπει να προβλέψεις ότι τα records πρέπει να έχουν μοναδικό όνομα το κάθε ένα, και φυσικά όλο αυτό το σύστημα είναι χάλια προσέγγιση αν το κρίνεις βάσει τεχνικών χαρακτηριστικών. Αλλά είναι καλό σαν πρώτη επαφή για εξάσκηση.

Δημοσ.

Αφού φαντάζομαι ότι γράφεις την αρχική καταχώρηση με fprintf, ο τρόπος να τη διαβάσεις πίσω στη μνήμη (αν δεν το έχεις κάνει ήδη) είναι η fscanf.

 

Απο κει και πέρα, η δουλειά θα γίνει σε κάποιο loop ως εξής:

 

  • σημειώνεις τον τρέχοντα file pointer με ftell()
  • διαβάζεις record με fscanf
  • αν το record δεν είναι αυτό που ψάχνεις, loop
  • αν είναι, τότε αλλάξεις το score στη μεταβλητή που διάβασε μόλις τώρα η fscanf, κάνεις fseek στην τελευταία τιμή που σημείωσες από την ftell και ξανά fprintf, γράφοντας έτσι την καινούρια τιμή πάνω από την παλιά

 

Φυσικά θα πρέπει να προβλέψεις ότι τα records πρέπει να έχουν μοναδικό όνομα το κάθε ένα, και φυσικά όλο αυτό το σύστημα είναι χάλια προσέγγιση αν το κρίνεις βάσει τεχνικών χαρακτηριστικών. Αλλά είναι καλό σαν πρώτη επαφή για εξάσκηση.

 

Ευχαριστώ για την απάντηση θα το κοιτάξω!

 

και ναι εντάξει ακόμα εξάσκηση κάνω..

 

και αν έχεις 5 παίκτες με το ίδιο όνομα τι θα κάνεις?

ποιο θα αλλάζεις κάθε φορά?

 

μήπως λείπει κάτι από την δομή σου?

 

 

Ναί όντως έχεις δίκιο αυτο όμως θα το ψάξω αργότερα..

Δημοσ.

Αν το πλήθος των σκορ είναι περιορισμένο, π.χ. κρατάς μόνο top 5 ή top 10, είναι πολύ πιο εύκολο να ξαναγράφεις όλο το αρχείο από την αρχή κάθε φορά...

 

>
int main( void )
{
struct player {
	char onoma[30];
	int vathmos;
} topscores[ 10 ] = { {"", 0} };    /* top 10 */

...
calc_scores( topscores, ... );
...
FILE *fp = fopen( "scores.dat", "wb");
fwrite( topscores, sizeof(player), 10, fp );
fclose( fp );
...
return 0;
}

 

προφανώς με τους κατάλληλους ελέγχους.

 

EDIT:

 

Και για να διαβάζεις το αρχείο στον πίνακα topscores, χρησιμοποιείς την...

 

>
fread( topscores, sizeof(player), 10, fp );

Δημοσ.

Διαβαζεις το αρχειο σου με fread() μεχρι να βρεις τον player που θες, κανεις fseek() στην βαθμολογια του και μετα με fwrite() γραφεις την νεα τιμη.

 

 

Αφού φαντάζομαι ότι γράφεις την αρχική καταχώρηση με fprintf, ο τρόπος να τη διαβάσεις πίσω στη μνήμη (αν δεν το έχεις κάνει ήδη) είναι η fscanf.

Σε binary files το IO γινετε με freed() - fwrite()

 

Αν το πλήθος των σκορ είναι περιορισμένο, π.χ. κρατάς μόνο top 5 ή top 10, είναι πολύ πιο εύκολο να ξαναγράφεις όλο το αρχείο από την αρχή κάθε φορά...

 

>
int main( void )
{
struct player {
	char onoma[30];
	int vathmos;
} topscores[ 10 ] = { {"", 0} };    /* top 10 */

...
calc_scores( topscores, ... );
...
FILE *fp = fopen( "scores.dat", "wb");
fwrite( topscores, sizeof(player), 10, fp );
fclose( fp );
...
return 0;
}

 

προφανώς με τους κατάλληλους ελέγχους.

 

EDIT:

 

Και για να διαβάζεις το αρχείο στον πίνακα topscores, χρησιμοποιείς την...

 

>
fread( topscores, sizeof(player), 10, fp );

πρωτον και κυριο, δεν τον ενδιαφερει το performance και δευτερον τα αρχεια μπορει να τα περνει ετοιμα. οποτε δεν μπορει να κανει υποθεσεις για το μεγεθος τους.

 

Δημοσ.

...

πρωτον και κυριο, δεν τον ενδιαφερει το performance και δευτερον τα αρχεια μπορει να τα περνει ετοιμα. οποτε δεν μπορει να κανει υποθεσεις για το μεγεθος τους

Που τα είδες να αναφέρονται αυτά (σίγουρα όχι πάντως από τον ts) ;

Δημοσ.
φυσικά όλο αυτό το σύστημα είναι χάλια προσέγγιση αν το κρίνεις βάσει τεχνικών χαρακτηριστικών. Αλλά είναι καλό σαν πρώτη επαφή για εξάσκηση.

Τι;;; Μια χαρα ειναι grin.png

Αν θελει κατι παραπανω τοτε

 

 

1α) download

1β) download

2) learn

3) Αστους αλλους να ψαχνονται για performance

Δημοσ.

Τι;;; Μια χαρα ειναι grin.png

Αν θελει κατι παραπανω τοτε

 

 

1α) download

1β) download

2) learn

3) Αστους αλλους να ψαχνονται για performance

 

Ας μη γινόμαστε υπερβολικοί... δε λέω, αν θέλεις να κάνεις σοβαρή δουλειά ένας in-process server του στυλ sqlite είναι πιθανόν η καλύτερη λύση, αλλά αυτό δε σημαίνει ότι δεν έχει νόημα να ψαχτεί κάποιος λίγο παραπάνω. Έτσι ξερά που το θέτεις είναι σα να λες ότι από data structures μόνο το array χρειάζεται να ξέρει κανείς (γιατί ακριβώς γι' αυτό μιλάμε, array serialized σε αρχείο).

Δημοσ.

Διαβαζεις το αρχειο σου με fread() μεχρι να βρεις τον player που θες, κανεις fseek() στην βαθμολογια του και μετα με fwrite() γραφεις την νεα τιμη.

 

 

Αυτές τις συναρτήσεις χρησιμοποιώ:

 

>

struct player
{
      char onoma[30];
      int vathmos;
      
}players,player1,player2;


           while(!feof(fp))// μέχρι το τέλος του αρχείου...
           {
                             
                          fread(&players,sizeof(struct player),1,fp); //καταχωρώ κάθε φορά στην μεταβλητή players το όνομα και τον βαθμό
                             
                          fores++;
                             
                             if(strcmp(player1.onoma,players.onoma)==0)//όταν βρώ το όνομα...
                             {
                                                                     
                                                                      
                                                                      fseek(fp,fores*sizeof(struct player),0);// πηγαίνω στην αρχή του σημείου που θα αλλάξω

                                                                      fwrite(&player1,sizeof(struct player),1,fp); //και γράφω την μεταβλητή player1 στην οποία υπάρχει το όνομα και ο καινούργιος βαθμός

                                                                      break;
                             }
            }
                       

 

Τι κάνω λάθος;

Δημοσ.

fseek(fp,fores*sizeof(struct player),0);// πηγαίνω στην αρχή του σημείου που θα αλλάξω

 

fwrite(&player1,sizeof(struct player),1,fp); //και γράφω την μεταβλητή player1 στην οποία υπάρχει το όνομα και ο καινούργιος βαθμός

 

 

για δοκίμασε έτσι

 

>
fseek(fp,sizeof(struct player)*(-1),SEEK_CUR);
fwrite(&player1,sizeof(struct player),1,fp);

Δημοσ.

Επειδή απ'ότι φαίνεται είσαι καινούργιος στον προγραμματισμό, αν σκοπεύεις να ασχοληθείς σοβαρά με εφαρμογές σε C πρέπει να ξέρεις ότι η fwrite και η fread δεν είναι portable συναρτήσεις. Ο λόγος είναι πως γράφουν τα bytes ακριβώς όπως τα βρίσκουν από τη RAM στο αρχείο κι έτσι όταν πας τα αρχεία/πρόγραμμα σε διαφορετικό σύστημα, το endianess μπορεί να είναι διαφορετικό και να διαβάζεις τα δεδομένα ανάποδα! Επίσης και σε ίδιο endianess να πας μπορεί να υπάρξουν προβλήματα με ta paddings των αρχείων. Οπότε καλύτερα να ξεκινήσεις να τις αποφεύγεις και να χρησιμοποιείς fprintf, fscanf μέχρι να προχωρήσεις σε POSIX.

Δημοσ.

Δεν δουλεύει.

 

δες το και σε πρόγραμμα

 

>
#include<stdio.h>
#include<stdlib.h>
#include <string.h> 

long currentPlayer=0;

struct player{
      char onoma[30];
      int vathmos; 
}temp1;

void eisagwgh();
void ektupwsh();
void diorthwsh();


int menou();

   FILE *fp;


int counter=0;

int main(){
       int epilogi;
       do{
               epilogi=menou();
               switch(epilogi){
                       case 1:
                               eisagwgh();
                               break;
                       case 2:
                               ektupwsh();
                               break;
                       case 3:
                               diorthwsh();
                               break;
                       case 0:
                               printf("exodos:\n");
                               break;
                       default:
                               printf("error:\n");
                               break;
               }
       }while(epilogi!=0);
       getchar();
       return 0;
}

//menou epilogwn

       int menou(){
               int ep;
               printf("\n\nmenou epilogwn:\n");
               printf("========================\n");
               printf("1.eisagwgh\n");
               printf("2.ektupwsh\n");
               printf("3.diorthwsh\n");
               printf("0.exodos\n");
               printf("========================\n");
               printf("Dwse epilogh:\n");
               scanf("%d",&ep);getchar();
               return ep;
       }

//eisagwgh


       void eisagwgh(){
           fp=fopen("players.dat","a+");//α+  ανοίγει το αρχείο για να το συμπληρώσει.Αν δεν το
                                           //βρει το δημιουργεί
           if(fp){//αν υπάρχει το αρχείο τότε
               fseek(fp,0,SEEK_END);//πήγαινε στο τέλος του
           }
           printf("dwse onoma:");
           scanf("%s",temp1.onoma);getchar();
           printf("dwse vathmo:");
           scanf("%d",&temp1.vathmos);getchar();
           fwrite(&temp1,sizeof(struct player),1,fp);
           fclose(fp);
       }

//ektupwsh

       void ektupwsh(){
           fp=fopen("players.dat","r");
           if(!fp)
               printf("To arxeio den uparxei\n");
           else{
               printf("\nARXEIO PAIKTWN\n");
               struct player temp;
               while(fread(&temp,sizeof(struct player),1,fp))
                   printf("name=%s vathmos=%d\n",temp.onoma,temp.vathmos);
               fclose(fp);
           }
       }


//diorthwsh

   void diorthwsh(){
       int i,N;
       char onom[30];
       printf("dwse onoma\n");
       scanf("%s",&onom);getchar();
       fp=fopen("players.dat","r+");
       if(!fp)
           printf("den uparxei to arxeio\n");
       else{
           fseek(fp,0,SEEK_END);
           N=ftell(fp)/sizeof(struct player);//αριθμός εγγραφών στο αρχείο
           fseek(fp,0,SEEK_SET);
           for(i=0;i<N;i++){
               fread(&temp1,sizeof(struct player),1,fp);
               if(strcmp(temp1.onoma,onom)==0){
                   printf("dwse neo vathmo<%d>:",temp1.vathmos);
                   scanf("%d",&temp1.vathmos);getchar();
                   fseek(fp,sizeof(struct player)*(-1),SEEK_CUR);
                   fwrite(&temp1,sizeof(struct player),1,fp);
                   break;
               }
           }
           fclose(fp);
       }

    }

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...