Avatar billede hhdsleizer Nybegynder
21. februar 2004 - 19:25 Der er 16 kommentarer og
1 løsning

gemme og hente data til highscore

Hej eksperter
Jeg har efterhånden fået lavet et program hvor man kan handle med diverse varer. Det eneste jeg mangler er en highscore liste til at fortælle hvem der har klaret sig bedst igennem tiderne... Det jeg ikke helt ved hvordan jeg skal gribe an er hvordan jeg gemmer navn, score og placering i en fil og så henter dem ud igen. jeg har tænkt mig at gemme dem i variabler hver for sig. men hvordan kan jeg have alle disse variabler gemt i en fil for derefter at læse dem ind igen når jeg har brug for og sådan at de rigtige værdier kommer i de rigtige variabler?

Programmet er lavet i mfc

Håber i kan hjælpe

Sleizer
Avatar billede arne_v Ekspert
21. februar 2004 - 20:09 #1
Du laver et bestemt fil format f.eks. navn og score adskilt af komma med
1 spiller per linie.

Relativt nemt både at skrive og læse.
Avatar billede hhdsleizer Nybegynder
21. februar 2004 - 21:00 #2
ok? men hvordan henter jeg dem ind og hvordan skriver jeg til filen? hvilken funktion skal jeg bruge? har du evnt et lille eksempel eller lign?

Sleizer
Avatar billede arne_v Ekspert
21. februar 2004 - 22:31 #3
En ren C demo:

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

#define FILENAME "score.dat"

void showall()
{
  int score;
  char line[100], name[100],*p;
  FILE *fp = fopen(FILENAME,"r");
  if(fp==NULL) return;
  while(!feof(fp))
  {
      if(!fgets(line,sizeof(line),fp)) break;
      p = strrchr(line,' ');
      score = atoi(p);
      *p = '\0';
      strcpy(name,line);
      printf("%s %d\n",name,score);
  }
  fclose(fp);
}

void add(char *name,int score)
{
  FILE *fp = fopen(FILENAME,"a");
  fprintf(fp,"%s %d\n",name,score);
  fclose(fp);
}

int main()
{
  printf("1:\n");
  showall();
  add("a b c",100);
  printf("2:\n");
  showall();
  add("x y z",200);
  printf("3:\n");
  showall();
  add("nn",300);
  printf("4:\n");
  showall();
  return 0;
}
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 00:31 #4
er der ikke en måde man slette hele inholdet af en fil? altså slette alt i score.dat i dette tilfælde? bare fordi jeg ville syntes det var smartest at hente alle data ind og evnt ændre nogen hvis en highscore var blevet stykket og så derefter skrive det hele i filen igen. eller en måde at overskrive?
Avatar billede bertelbrander Novice
22. februar 2004 - 00:40 #5
Du kan åbne filen med "w" i stedet for "a", så bliver alt indhold slettet.
Avatar billede bertelbrander Novice
22. februar 2004 - 02:02 #6
Man kunne lave en C++ version:

#include <string>
#include <iostream>
#include <fstream>
#include <map>
#include <cstdlib>
#include <algorithm>

using namespace std;

#define FILENAME "score.dat"

int main()
{
  // Our High Score Table
  multimap<int, string> HighScoreTable;

  // Read from file
  ifstream is(FILENAME);
  while(is)
  {
    int i;
    string s;
    is >> i >> s;
    if(is)
      HighScoreTable.insert(make_pair(i, s));
  }

  // Enter new entry
  int NyHighScore;
  string NyNavn;
  cout << "Indtast ny HighScore og navn: ";
  cout.flush();
  cin >> NyHighScore >> NyNavn;
  HighScoreTable.insert(make_pair(NyHighScore, NyNavn));

  // Only store 10 entries
  while(HighScoreTable.size() > 10)
    HighScoreTable.erase(HighScoreTable.begin());

  // Write to file, overwrite everything
  ofstream os(FILENAME);
  if(!os)
  {
    cout << "Failed to open output!" << endl;
    return EXIT_FAILURE;
  }

  for(multimap<int, string>::iterator i = HighScoreTable.begin(); i != HighScoreTable.end(); ++i)
  {
    cout << i->first << " " << i->second << endl;
    os << i->first << " " << i->second << endl;
  }

  return EXIT_SUCCESS;
}
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 11:24 #7
i det c eksemple ville jeg gerne har et name og score array som så kunne holde styr på fx 10 navne og 10 score...

jeg har prøvet med dette:

void showall()
{
  int score[100];
  char line[100], name[100],*p;
  FILE *fp = fopen(FILENAME,"r");
  if(fp==NULL) return;
  for(int i=0;!feof(fp); i++)
  {
      if(!fgets(line,sizeof(line),fp)) break;
      p = strrchr(line,' ');
      score[i] = atoi(p);
      *p = '\0';
      strcpy(name,line);
      std::cout << name[i] << " " << score[1] << std::endl;
  }
  fclose(fp);
}

void add(char *name,int score)
{
  FILE *fp = fopen(FILENAME,"a");
  fprintf(fp,"%s %d\n",name,score);
  fclose(fp);
}

int main()
{
  printf("1:\n");
  add("Sleizer",100);
  showall();
  system("pause");
  return 0;
}

problemet er at score ser ud til at blive uinitialiseret i starten og navnet kommer i små bidder af 1 bogstav pr. styk? hvad gør jeg forkert... jeg behøes ikke kunne udskrive det hele flot eller noget. skal bare kunne smide de rigtige værdier og navne i de rigtige pladser i arrays'ne

Sleizer
Avatar billede arne_v Ekspert
22. februar 2004 - 11:42 #8
name skal så være et 2D array.

Mit eksempel modificeret:

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

#define FILENAME "score.dat"

void showall()
{
  int i,n,score[25];
  char line[100], name[25][100],*p;
  FILE *fp = fopen(FILENAME,"r");
  if(fp==NULL) return;
  n = 0;
  while(!feof(fp))
  {
      if(!fgets(line,sizeof(line),fp)) break;
      p = strrchr(line,' ');
      score[n] = atoi(p);
      *p = '\0';
      strcpy(name[n],line);
      n++;
  }
  fclose(fp);
  for(i=0;i<n;i++)
  {
      printf("%s %d\n",name[i],score[i]);
  }
}

void add(char *name,int score)
{
  FILE *fp = fopen(FILENAME,"a");
  fprintf(fp,"%s %d\n",name,score);
  fclose(fp);
}

int main()
{
  printf("1:\n");
  showall();
  add("a b c",100);
  printf("2:\n");
  showall();
  add("x y z",200);
  printf("3:\n");
  showall();
  add("nn",300);
  printf("4:\n");
  showall();
  return 0;
}
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 19:44 #9
ok.. er ved at have fået det til at virke... men mangler lige det sidste.. kan sagtens indlæse filen rigitgt nu problemet ligger i at skrive den sådan at hvir der kommer en værdi der er mellem tidligere værdier skal værdien presses ind imellem... der skal i alt være 50 pladser på listen og min kode ser ud på følgende måde indtil videre:

void CHigh::Add()
{
    FILE *fp = fopen(FILENAME,"w");
    int valg2 = 0;

    for(int i=0;i<50;i++)
    {
        if(m_nPenge < score[i])
        {
            fprintf(fp,"%s %d\n",name[i],score[i]);
        }
        if(m_nPenge >= score[i] && valg2 == 0)
        {
            for(int f=49; f > i; f--)
            {
                        //Hvad skal der stå her?
            }
        }
           
            break;
        }

    fclose(fp);
}

har prøvet meget i for løkken.. men hvad skal der stå.. meningen er at når den finder en værdi der er lig eller større en en p listen skal ens score føres ind og alle andre rykkes ned... hvis der er 50 score på listen skal den nederste forsvinde sådanat der i alt kun er 50 på listen...
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 19:45 #10
kan selvfølgelig også være det kan løses på en anden mere smart måde.. dette var bare måden det hele så mest logisk ud i mit hoved...
Avatar billede arne_v Ekspert
22. februar 2004 - 20:21 #11
Det må vel være noget a la:

// check om der overhovedet skal ændres i filen
if(m_nPenge > score[49])
{
    FILE *fp = fopen(FILENAME,"w");
    int fnd = 0;
    for(int i=0;i<49;i++)
    {
        if(!fnd && (m_nPenge > score[i]))
        {
            fprintf(fp,"%s %d\n","me",m_nPenge);
            fnd = 1;
        }
        fprintf(fp,"%s %d\n",name[i],score[i]);
    }
    fclose(fp);
}
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 20:38 #12
min funktion ser nu ud på følgende måde:

void CHigh::ShowAll()
{
    m_ctrlHigh.DeleteAllItems();
  FILE *fp = fopen(FILENAME,"r");
  if(fp==NULL) return;
  n = 0;
  while(!feof(fp))
  {
      if(!fgets(line,sizeof(line),fp)) break;
      p = strrchr(line,' ');
      score[n] = atoi(p);
      *p = '\0';
      strcpy(name[n],line);
      n++;
  }
  fclose(fp);
  for(i=0;i<n;i++)
  {
      navn[i] = name[i];
    penge[i] = score[i];
  for(i=0;i<50;i++)
  {
      m_nPlads = i+1;
      sprintf(m_chPlads, "%d", m_nPlads);
      m_strPlads = m_chPlads;
      m_ctrlHigh.InsertItem(i, m_strPlads, 0);
      m_ctrlHigh.SetItemText(i,1,name[i]);
      sprintf(m_chScore, "%d", score[i]);
      m_ctrlHigh.SetItemText(i,2,m_chScore);
  }
  }
}

void CHigh::Add()
{
// check om der overhovedet skal ændres i filen
if(m_nPenge > score[49])
{
    FILE *fp = fopen(FILENAME,"w");
    int fnd = 0;
    for(int i=0;i<49;i++)
    {
        if(!fnd && (m_nPenge > score[i]))
        {
            fprintf(fp,"%s %d\n","navn",m_nPenge);
            fnd = 1;
        }
        fprintf(fp,"%s %d\n",name[i],score[i]);
    }
    fclose(fp);
}
}

det er din kode med lidt ændringer... mest i udksrivningen..

men i linjen
score[n] = atoi(p);

giver debuggeren en Unhandled exception at 0x0049d3dc???
hvad er der galt?
jeg har lagt variablerne ind i klassen for min dialog boks

CListCtrl m_ctrlHigh;

CString m_strNavn;
int m_nPenge;
int m_nSlut;
int m_nPlads;
char m_chPlads[100];
char m_chScore[100];
CString m_strPlads;
int i,n,score[50];
char line[100], name[50][100],*p;
CString navn[50];
int penge[50];

men kan ikke se fejlen? hvis du er i tvivl om nogle af navnene i koden eller hvad de er skal du bare spørge...
Avatar billede arne_v Ekspert
22. februar 2004 - 20:41 #13
score[n] = atoi(p);

bør kun kunne give fejl, hvis der enten ingen mellerum er i en linie
eller der er mere end 50 linier
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 20:53 #14
der er noget i filen... jeg kan også godt se dem indtegnet i min list control... når der kommer fejl er når jeg klader ShowAll() efter jeg har kaldt Add()
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 21:09 #15
når jeg har kørt Add() er score.DAT filen vokset til en størrelse over 100 kb og fuld af en masse tegn... så der må være et sted i Add() der laver rag i det..
Avatar billede arne_v Ekspert
22. februar 2004 - 21:11 #16
Jeg tror at problemet ligger i:

for(int i=0;i<49;i++)

som er OK, *HVIS* der er 50 i top score.

Men hvis ikke der er det, så bruger man name og score elementer som ikke har
fået nogen værdi.

49 må skulle erstattes med (n-1)
Avatar billede hhdsleizer Nybegynder
22. februar 2004 - 21:34 #17
NU VIRKER DET:D
mange tusind tak for hjælpen... smider lige nogle flere points i hovedet på dig efter alt det hjælp.

Sleizer
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester