• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Sortowanie w pliku tekstowym

0 głosów
250 wizyt
pytanie zadane 7 czerwca 2019 w C i C++ przez Dew Początkujący (290 p.)

Cześć, słuchajcie piszę grę konsolową na projekt gdzie wymogiem jest ranking wyników. zrobiłem zapis nicków i wyniku do pliku ale wykładam się na posortowaniu tego w ranking. Jestem już po kilku książkach na temat i sortowania bąbelkowego, i wczytywania linii i robienia splitu i sortowania vectorow no ale nie wiem, nie umiem sobie tego po prostu wyobrazic w taki sposob by przelozyc to na kod. może byłby ktoś mi to w stanie logicznie wytłumaczyć? Przyesyłam fragment kodu który mi zapisuje wyniki do pliku tekstowego tak jak chce:

d blockshoot()
{
	string nick;
	cout<<"Write your name: ";
	cin>>nick;
	cout<<"Your name is: "<<nick<<endl;
	Sleep(500);
	system("cls");
	ramka();
	char ch1, aa = 196, ee = 'q';
	int k,x,y,xp;
	kierunek(&k);
	int kx = k;
	int ky = k;
	int kxp = k;
	paletka(&xp);
	pilka(&x, &y);
	int p;
	punkty(&p);
	int punkty = p;
	while (ee == 'q')
	{
		if (y == 17 && (x >= xp) && (x <= xp + 4))
		{
			ky = ky * -1;
			punkty = punkty + 1;
		}
		if (y == 18 && (x >= xp) && (x <= xp + 4))
		{
			ky = ky * -1;
		}
		if (y == 19)
		{
			punkty = punkty - 1;
		}
		if (x > 38 || x < 3)
		{
			kx = kx * -1;
		}
		if (y > 18 || y < 3)
		{
			ky = ky * -1;
		}
		if (xp > 34 || xp < 3)
		{
			kxp = kxp * -1;
		}
		xp = xp + kxp;
		x = x + kx;
		y = y + ky;
		while (_kbhit())
		{
			ch1 = getch();
			if (ch1 == 121)
			{
				ee = 'e';
				cout<<"Save your game?"<<endl;
				if(_getch() == 121)
				{
					ofstream ranking("rank.txt", ios::app);
					ranking<<nick<<" "<<punkty<<endl;
					ranking.close();
				}
			}
			if (ch1 == ' ' && xp > 3 && xp < 34)
			{
				kxp = kxp * -1;
			}
		}
			gotoxy(x, y);
			cout << "o";
			Sleep(5);
			gotoxy(xp, 17);
			cout << aa << aa << aa << aa << aa << endl;
			gotoxy(42, 2);
			cout << "SCORES:";
			gotoxy(50, 2);
			cout << punkty;
			Sleep(50);
			gotoxy(x, y);
			cout << " ";
			gotoxy(xp, 17);
			cout << "     ";
			gotoxy(50, 2);
			cout << "   ";
				}
}

pozdrawiam!

7 odpowiedzi

+1 głos
odpowiedź 7 czerwca 2019 przez adrian17 Ekspert (320,820 p.)
        if (y == 17 && (x >= xp) && (x <= xp + 4))
        {
            ky = ky * -1;
            punkty = punkty + 1;
        }
        if (y == 18 && (x >= xp) && (x <= xp + 4))
        {
            ky = ky * -1;
        }
        if (y == 19)
        {
            punkty = punkty - 1;
        }
        if (x > 38 || x < 3)
        {
            kx = kx * -1;
        }
        if (y > 18 || y < 3)
        {
            ky = ky * -1;
        }
        if (xp > 34 || xp < 3)
        {
            kxp = kxp * -1;
        }

Um... co to wszystko jest? Te wszystkie 'ee', 'aa' etc?

O co chodzi z tymi wszystkimi dziwnymi funkcjami które biorą wskaźniki, których wartości używasz tylko żeby je przypisać do innej zmiennej?

    int p;
    punkty(&p);
    int punkty = p;

Problem w tym że tego kodu ogólnie nie można zrozumieć, przez co nawet nie wiem co tutaj chciałbyś sortować.

komentarz 7 czerwca 2019 przez Dew Początkujący (290 p.)

Myślałem, że logicznie to wytłumaczyłem, ale już śpieszę z tłumaczeniem jeszcze raz. Zmienne o które pytasz są związane sztywno z grą i nie ma to żadnego znaczenia w tym co chce sortować. Sedno tkwi w zmiennych nick oraz punkty. 

	string nick;
	cout<<"Write your name: ";
	cin>>nick;
	cout<<"Your name is: "<<nick<<endl;
	Sleep(500);
	system("cls");

Tą częścią kodu załatwiam sprawę podania nicku oraz jej zapisanie w zmiennej nick natomiast

	cout<<"Save your game?"<<endl;
				if(_getch() == 121)
				{
					ofstream ranking("rank.txt", ios::app);
					ranking<<nick<<" "<<punkty<<endl;
					ranking.close();
				}

tą częścią kodu po spełnieniu warunków robię tak jakby nazwijmy to zapis gry, przez co plik rank.txt wygląda tak:

Jan 10
Adam 25
Maria 12
Leszek 594
Marcin 3

ponieważ oczywiście dodaje mi każdy kolejny stan aktualnie zdobytych punktów w nowej rozgrywce. To co chce zrobić to to, by posortowało mi te dane w ranking w stylu:

Leszek 594
Adam 25
Maria 12
Jan 10
Marcin 3

Zdaję sobie sprawę z tego że wygląda to brzydko ale rozdzielenie to na voidy zostawię sobie na koniec, gdy już załatwię sprawę najważniejszych rzeczy

Edit: Wiem jak wyglądają te wskaźniki, pozostały one po pierwszej części zadania za które dostałem już ocenę, program działał, ocena pozytywna i zadowalająca więc wolę zając się doposażeniem tego programu w kolejne wymagane rzeczy

0 głosów
odpowiedź 7 czerwca 2019 przez Dew Początkujący (290 p.)

Byłbym zapomniał. Funkcja wyświetlająca mi ranking w konsoli wygląda następująco:

void ranking()
{
	cout<<"ranking"<<endl<<endl;
	fstream ranking;
	ranking.open("rank.txt", ios::in);
	if(ranking.good()==false)
	{
		cout<<"Brak pliku";
		exit(0);
	}
	string linia;
	while(getline(ranking, linia))
	{
			cout<<linia<<endl;
			
	}
	ranking.close();
}

 

komentarz 8 czerwca 2019 przez niezalogowany

jak możesz używać kontenera set to to https://forum.pasja-informatyki.pl/433710/tablica-rekordow-c#c434056 przeróbkach będzie działało tylko zamiast 

 //  a->scores.insert(std::move(to_string(this->score)+" ------------"+this->name));
    a->scores.insert(std::move(to_string(this->score)+this->name+"------------ "));

i

  //std::set<string> ::iterator it;
   // for (it=t.scores.begin(); it!=t.scores.end(); it++)
     //   cout<<*it<<endl;
        for (auto&x:t.scores){
            stringstream ssx(x);
        int xi=0; string xs="";
        ssx>>xi>>xs;
        cout<<xs<<xi<<endl;
        }

i funkcja adgetline() w Record

addgetline (ifsteram &plik)
{
........
getline(plik ,dane)
stringsteam ss(dane);
......
//i nie w destruktorze 
a->scores.insert(std::move(to_string(this->score)+this->name+"------------ "));
}

Ale zastrzegam ze to bardzo brzydkie rozwiązanie i można to zrobić prościej.

0 głosów
odpowiedź 7 czerwca 2019 przez adambarabasz Nowicjusz (140 p.)
Ale chcesz sortować dopiero przy wyświetlaniu rankingu, czy od razu dodawać je w dobrej kolejności do pliku?
Jeżeli chcesz je sortować przy wyświetlaniu, to proponuję wczytać zawartość pliku do tablicy dwuwymiarowej, a następnie posortować na podstawie wyniku.
Pisałeś o sortowaniu bąbelkowym, więc wystarczy że będziesz zamieniał ze sobą miejscami i wyniki, i nicki im odpowiadające.
komentarz 7 czerwca 2019 przez Dew Początkujący (290 p.)
Dopiero przy wyświetleniu. Czy to nie koliduje ze sobą że wczytując linie będę mieć jedną zmienną typu string a drugą int i będę chciał je razem wrzucić do tablicy? Dziękuję za odpowiedź
0 głosów
odpowiedź 8 czerwca 2019 przez AuriattaDev Początkujący (390 p.)

Pobierz dane z pliku z rankingiem do tablicy używając do tego pętli. Potem do sortowania użyj sort.

Polecam używać nazw zmiennych w jednym języku, najlepiej angielskim(dobre nawyki). Staraj się nie używać nazw typu eee. To robi tylko bajzel w kodzie.

komentarz 9 czerwca 2019 przez Dew Początkujący (290 p.)
Zmienną nazwał profesor na wykładzie nic nie poradzę:D
0 głosów
odpowiedź 8 czerwca 2019 przez Dew Początkujący (290 p.)

Znalazłem kod, który po odpowiednich modyfikacjach, spełniałby rolę, którą by musiał spełniać. Oto on:

#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<algorithm>

using namespace std;

struct student{  //stworzenie własnego typu o nazwie student
  char nazwisko[25];
  double srednia;
  bool operator < (const student &x)const //zdefiniowanie zachowania się
  {                //operatora < potrzebnego przy sortowaniu
    return srednia>x.srednia;
  }
  
};

int main()
{
  //stworzenie studentów i przypisanie do nich przykładowych danych
  student studenci[] = { //tablica będzie się składać z 10 studentów
    {"Kowalski",  3.12},
    {"Kasprowicz",  4.40},
    {"Nowak",    6.00},
    {"Kosak",    5.44},
    {"Nasiadka",  5.32},
    {"Nowicki",    3.44},
    {"Kanigowski",  4.00},
    {"Danusiak",  4.00},
    {"Dworznik",  4.20},
    {"Kaminski",  3.00}
  };
  cout<<"Dane studentów przed sortowaniem: "<<endl;
  for(int i=0;i<10;i++)
    cout<<"Nazwisko: "<<studenci[i].nazwisko
    <<", srednia: "<<fixed<<setprecision(2)
    <<studenci[i].srednia<<endl;
  
  sort(studenci,studenci+10); //sortowanie studentów
  
  cout<<endl;
  cout<<"Dane studentów po sortowaniu: "<<endl;
  for(int i=0;i<10;i++)
    cout<<"Nazwisko: "<<studenci[i].nazwisko
    <<", srednia: "<<fixed<<setprecision(2)
    <<studenci[i].srednia<<endl;
  system("pause");
  return 0;
}

Czy macie państwo pomysł jak w miejscu gdzie na sztywno są przypisane dane do tablicy pobrać moje dane z pliku? Pozdrawiam i dziękuje za duzy odzew

komentarz 9 czerwca 2019 przez niezalogowany

Od razu użyj vectora, a resztę to już normalnie operatorem >>

int main()
{
	std::vector<Student> studenci; // include <vector>

	std::ifstream file("rank1.txt");
	if (file.is_open()) 
	{
		std::string name;
		double avg;
		while (file >> avg >> name) 
		{
			studenci.push_back(Student{ name, avg });
		}
	}

	studenci.push_back({"Leonard", 12.32});

	std::sort(studenci.begin(), studenci.end());

	for (std::size_t i = 0; i < studenci.size(); ++i)
	{
		std::cout << studenci[i].srednia << " " << studenci[i].nazwisko << "\n";
	}
    // ...
}
0 głosów
odpowiedź 10 czerwca 2019 przez Dew Początkujący (290 p.)
Dzięki wielkie, problem rozwiązany a temat myślę, że wyczerpany i przyda się innym :D
–1 głos
odpowiedź 8 czerwca 2019 przez mrspock1 Mądrala (6,400 p.)
Ja bym użył do tego komponentu TStringList. Wszystko może być w jednej linii tekstowej. Trzeba tylko zmienić porównanie dwóch elementów w procedurze sortującej i wstawić tam funkcję porównującą, która wyodrębni tą część obu linii która decyduje o sortowaniu. Porównać je według wymaganego sposobu i już wiemy która linia jest przed którą. Wtedy zamieniamy linie ze sobą. Ale bardziej eleganckie podejście to podzielić linię na pola i użyć bazy danych. Wtedy bez trudu sortuje się linię według wybranego pola, z użyciem indeksu jest szybciej.

Podobne pytania

0 głosów
1 odpowiedź 184 wizyt
pytanie zadane 30 lipca 2020 w Java przez lucyliu Początkujący (370 p.)
–1 głos
1 odpowiedź 168 wizyt
pytanie zadane 30 stycznia 2018 w C i C++ przez Artur313 Użytkownik (790 p.)
0 głosów
2 odpowiedzi 1,189 wizyt
pytanie zadane 16 kwietnia 2019 w C# przez WojMen Początkujący (330 p.)

88,381 zapytań

136,985 odpowiedzi

305,728 komentarzy

58,644 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...