Stworzenie opcji "Dodaj pytanie" do gry "Milionerzy"

0

Witam,
muszę stworzyć opcję dodaj pytanie do gry milionerzy(konsolowa). Chodzi o to, by po wpisaniu np. 3 switch przeszedł do funkcji dodaj pytanie.

Dodaj pytanie powinno otworzyć plik tekstowy i na końcu dodać pytanie według struktury:

Poziom trudności, pytanie, odpowiedz 1, 2, 3, 4, poprawna.

Problemem jest to, że cin/scanf wczytuje do pierwszego białego znaku, a getline powoduje error.

Moje umiejętności są raczej poniżej poziomu newbie, więc proszę o sensowną pomoc bez zbędnych komentarzy typu co za debil.

Oto kod jaki napisałem, ale nie działa tak jak bym chciał (ale przynajmniej się kompiluje co już jest dla mnie sukcesem). Getline wywala error.

#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
struct baza_pytan 
{
	int poziom;	//Łatwe 1, Średnie 2, Trudne 3
	string pytanie;
	string odpowiedz1;
	string odpowiedz2;
	string odpowiedz3;
	string odpowiedz4;
	int poprawna;
};

int main()
{
	baza_pytan pytanie[1];
	
	printf("Wybierz poziom trudnosci: 1 Latwy, 2 Sredni, 3 Trudny:\n");
	scanf("%d",&pytanie[0].poziom);
	
	printf("Wpisz pytanie:\n");
	getline(cin, pytanie[0].pytanie);
	
	printf("Wpisz odpowiedz nr1:\n");
	getline(cin, pytanie[0].odpowiedz1);
	
	printf("Wpisz odpowiedz nr2:\n");
	getline(cin, pytanie[0].odpowiedz2);
	
	printf("Wpisz odpowiedz nr3:\n");
	getline(cin, pytanie[0].odpowiedz3);
	
	printf("Wpisz odpowiedz nr4:\n");
	getline(cin, pytanie[0].odpowiedz4);
	
	printf("Która odpowiedź jest poprawna 1-4:\n");
	scanf("%d",&pytanie[0].poprawna);

	fstream plik;
	plik.open("pytania.txt", ios::out);
	
	plik<<pytanie[0].poziom<<endl;
	plik<<pytanie[0].pytanie<<endl;
	plik<<pytanie[0].odpowiedz1<<endl;
	plik<<pytanie[0].odpowiedz2<<endl;
	plik<<pytanie[0].odpowiedz3<<endl;
	plik<<pytanie[0].odpowiedz4<<endl;
	plik<<pytanie[0].poprawna<<endl;
	
plik.close();

/*	FILE *plik;
	plik=fopen("pytania.txt","wt");
	
	fwrite(pytanie,sizeof(struct baza_pytan),1,plik);
	
	fclose(plik);
*/	
	system("pause");
	return 0;
}
}
3

jako ze to C++ to dodam pare uwag od siebie
0) wrzucaj kod w znaczniki code

  1. cstdlib zamiast stdlib.h
    standardowe bibloteki z c++ nie uzywaja rozszerzen h na koncu
    przyklad iostream czy fstream czy vector. Taka bardzo mala drobnostka
  2. deklarujesz rozmiar tablicy 1 a pozniej odwokujesz sie do indeksu 1 (czyli do obiektu drugiego) poczytaj jak dzialaja tablice i indeksowanie po tablicy. Tam powinno byc pytanie[0].odpowiedz3.** Dlatego Ci nie dziala**
  3. skoro c++ uzywaj cin i cout
  4. zamiast file uzywaj fstream
  5. czemu struktura a nie klasa? (mozna uzywac obu, ale pytanie czy Ty rozumiesz roznice miedzy nimi?)
  6. nie uzywaj system("pause") sa lepsze sposoby na zatrzymanie konsoli
0

Jeśli oczekujesz sensownej odpowiedzi to:

  1. Wstaw kod między <code><code class="cpp"></code></code>
  2. Wstaw treść błędu między <code class="none"></code> oraz linię kodu, której ten błąd dotyczy
0
  1. Poprawione
  2. Poprawione
  3. Poprawione
  4. W moim przypadku to jest mieszanie c z c++, bo w praktyce cin, cout nawet nie miałem, ale wiem co to
  5. szczerze powiem, że nie wiem co to klasa

Jeśli chodzi o mnie to ja wolę się zajmować sieciami komputerowymi, ale trzeba jakoś zdać programowanie, jestem z tego fatalny i bardzo dobrze o tym wiem.

Mając 20 godzin programowania, ciężko się czegoś nauczyć.

Coś już zaczęło działa, ale pomija wprowadź pytanie:

Wpisz pytanie:
Wpisz odpowiedź nr1:

A do pliku zapisuje jakieś śmieci.

0

@mafik1 pisz w jednym języku. Klasa od struktury różni się tym, ze w tej pierwsze z definicji wszystkie 'składniki' są prywatne, a w drugiej wszystkie publiczne.
Mama ci w domu udziela komputera? Nie mozesz programować sam ?

0

nie narzekaj, to w niczym Ci nie pomoze. A tylko denerwuje ludzi ktorzy chca Ci pomoc.

popraw tez 4. Pisalem ostatnio proste zapisywanie do pliku na podstawie tego mozesz sobie zmienic spokojnie Twoj kod

void SaveToFilePlayerName(std::string& originalName, std::string& newName)
{
	std::fstream fileStream;
	std::string fileName = "data.txt";
	fileStream.open(fileName, std::ofstream::trunc | std::fstream::out);
	fileStream << originalName << " " << newName;
	fileStream.close();	
}
 

a ze masz smieci to najprosciej bedzie debuggowac linijka po linijkce i zobaczyc czy dane sie zgadzaja. Nie uzywalem duzo FILE i nie wiem czy dobrze zapisujesz do pliku te dane (zapewne nie)
bo jak widzisz tutaj
http://ideone.com/zuOJew
wczytywanie danych dziala poprawnie. Cos masz nie tak z zapisywaniem do pliku. zrob na podstawiej mojej funkcji to Ci zacznie dzialac (poczytaj o tych flagach out i trunc i innych co robia)

edit: po komentarzu ktory dodales potrzebujesz flagi std::app (tylko i wylacznie)

0

Zedytowałem pierwszy post i w takiej wersji już zapisuje do pliku, ale dalej nie pyta o pytanie, o wszystko inne tak, ale pytanie pomija.

ios::app); Rozwiązałem nadpisywanie pliku, więc można już powoli tworzyć bazę pytań, gdy tylko uda się sprawić by pytał o pytanie.

Dzięki wielkie wszystkim którzy udzielają się w temacie. Dzięki Wam zaczyna to powoli działać tak jak chciałem.

PS. za chwilę przerobię printf, scanf itd. na cout, cin, żeby Was tak w oczy nie raziło:)

0

nie edytuj pierwszego postu tylko pokazuj w odpowiedziach jaki masz autkalny kod. Bo tak moje uwagi teraz odnosza sie do niczego

tak jak mowilem musisz uzyc odpowiedniej flagi
Flaga out tworzy NOWY plik, za kazdym razem. Wiec musisz ja usunac. Co potrzebujesz, to potrzebujesz flagi App (append czyli dodawaj)

0
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
struct baza_pytan 
{
	int poziom;	//Łatwe 1, Średnie 2, Trudne 3
	string pytanie;
	string odpowiedz1;
	string odpowiedz2;
	string odpowiedz3;
	string odpowiedz4;
	int poprawna;
};

int main()
{
	baza_pytan pytanie[1];
	
	cout<<"Wybierz poziom trudnosci: 1 Latwy, 2 Sredni, 3 Trudny:"<<endl;
	cin>>pytanie[0].poziom;
	
	cout<<"Wpisz pytanie:"<<endl;
	getline(cin, pytanie[0].pytanie);
	
	cout<<"Wpisz odpowiedz nr1:"<<endl;
	getline(cin, pytanie[0].odpowiedz1);
	
	cout<<"Wpisz odpowiedz nr2:"<<endl;
	getline(cin, pytanie[0].odpowiedz2);
	
	cout<<"Wpisz odpowiedz nr3:"<<endl;
	getline(cin, pytanie[0].odpowiedz3);
	
	cout<<"Wpisz odpowiedz nr4:"<<endl;
	getline(cin, pytanie[0].odpowiedz4);
	
	cout<<"Ktora odpowiedz jest poprawna 1-4:"<<endl;
	cin>>pytanie[0].poprawna;

	fstream plik;
	plik.open("pytania.txt", ios::out | ios::app);
	
	plik<<pytanie[0].poziom<<endl;
	plik<<pytanie[0].pytanie<<endl;
	plik<<pytanie[0].odpowiedz1<<endl;
	plik<<pytanie[0].odpowiedz2<<endl;
	plik<<pytanie[0].odpowiedz3<<endl;
	plik<<pytanie[0].odpowiedz4<<endl;
	plik<<pytanie[0].poprawna<<endl;
	
	plik.close();

/*	FILE *plik;
	plik=fopen("pytania.txt","wt");
	
	fwrite(pytanie,sizeof(struct baza_pytan),1,plik);
	
	fclose(plik);
*/	
	system("pause");
	return 0;
}

Teraz wygląda to tak, ale mimo wszystko pyta o poziom trudności i po wpisaniu wyskakuje:
Wpisz pytanie:
Wpisz odpowiedz nr1:

I dopiero tutaj pozwala coś wpisać i trafia to do odpowiedz1

0

Cały czas występuje ten sam problem, czyli omija wpisanie pytania, wygląda to tak:

Wybierz poziom trudnosci: 1 Latwy, 2 Sredni, 3 Trudny:
1
Wpisz tresc pytania:
Wpisz odpowiedz A:

PS. Czy do losowania pytań o różnych poziomach trudności lepiej będzie zapisać je do 3 osobnych plików: Łatwe, Średnie, Trudne i po przejściu pytań 1-4, grupa zmienia się na średnie, po przejściu 8 pytania na trudne, czy może zostać tak jak jest i uda się jakoś do losowania użyć poziomu pytań wpisanego do pliku.

int dodaj_pytanie()
{
	baza_pytan pytanie[1];
	
	cout<<"Wybierz poziom trudnosci: 1 Latwy, 2 Sredni, 3 Trudny:"<<endl;
	cin>>pytanie[0].poziom;
	
	cout<<"Wpisz tresc pytania:"<<endl;
	getline(cin, pytanie[0].pytanie);
		
	cout<<"Wpisz odpowiedz A:"<<endl;
	getline(cin, pytanie[0].odpowiedz1);
	
	cout<<"Wpisz odpowiedz B:"<<endl;
	getline(cin, pytanie[0].odpowiedz2);
	
	cout<<"Wpisz odpowiedz C:"<<endl;
	getline(cin, pytanie[0].odpowiedz3);
	
	cout<<"Wpisz odpowiedz D:"<<endl;
	getline(cin, pytanie[0].odpowiedz4);
	
	cout<<"Ktora odpowiedz jest poprawna a-d:"<<endl;
	cin>>pytanie[0].poprawna;

	fstream plik;
	plik.open("pytania.txt", ios::out | ios::app);
	
	plik<<pytanie[0].poziom<<endl;
	plik<<pytanie[0].pytanie<<endl;
	plik<<pytanie[0].odpowiedz1<<endl;
	plik<<pytanie[0].odpowiedz2<<endl;
	plik<<pytanie[0].odpowiedz3<<endl;
	plik<<pytanie[0].odpowiedz4<<endl;
	plik<<pytanie[0].poprawna<<endl;
	
	plik.close();

	cout<<endl;
	cout<<"Dodano pytanie, wcisnij ENTER"<<endl;

	return 0;
} 
0

Problem rozwiązany, wystarczyło dodać

cin.ignore();

przed getlinem z którym był problem

dodanie znacznika <code class="cpp"> - @furious programming

0

Doszedłem do etapu, gdy trzeba wylosować pytania, żeby zawsze nie były takie same. Czy jest możliwość wylosowania całej zawartości struktury? Chodzi o to, że nie mogę losować dowolnych miejsc w pliku od których getline ma pobierać linię, bo pytania są przykładowo od 1 do 7 linii, następne od 8 do 14 itd.

Ja wiedzę to na zasadzie:
Linie są kopiowane do struktury ( Linia od 1-7 struktura [0], 8-14 struktura [1] itd.), a potem randomem losuję jakieś cyfry i struktury o takich numerach będą wylosowanymi pytaniami.

Sorry, że to tak pomieszałem, ale zgubiłem się myśląc jak to zrobić, a do tego dochodzi jeszcze problem, że pierwsze 4 pytania powinny być brane ze struktur, których poziom jest równy 1, następny 4 pytania z poziom = 2, a ostatnie 4 z poziom =3.

1 użytkowników online, w tym zalogowanych: 0, gości: 1