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

Sortowanie w pliku tekstowym

VPS Starter Arubacloud
0 głosów
460 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 (344,100 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,420 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ź 352 wizyt
pytanie zadane 30 lipca 2020 w Java przez lucyliu Początkujący (370 p.)
–1 głos
1 odpowiedź 367 wizyt
pytanie zadane 30 stycznia 2018 w C i C++ przez Artur313 Użytkownik (790 p.)
0 głosów
2 odpowiedzi 1,607 wizyt
pytanie zadane 16 kwietnia 2019 w C# przez WojMen Początkujący (330 p.)

92,453 zapytań

141,262 odpowiedzi

319,086 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...