Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Random-luvut

Sivun loppuun

vesikuusi [10.02.2011 15:20:28]

#

Kirjoitan ohjelmaa, joka arpoo lukuja, joiden perusteella arvotaan sanoja ja niistä syntyy sitten lauseita. On kuitenkin ongelma: ohjelma arpoo kolme lukua väliltä 1-5 rand() funktiolla erillisissä alifunktioissa, mutta jostain syystä kaikki kolme lukua ovat aina samat, eivät vakiot, mutta samat... Käytän myös srand(time(NULL)) ja on myös kokeiltu srand(time(0)) Kääntäjä on g++ 4.3 ja järjestelmä Ubuntu 10.04 LTS. Ohjelman koodi alla:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>

using namespace std;

int x, y, z;

char valinta;
string tekija;
string verbi;
string paikka;

void arvo();
void print();
void arvo2();
void arvo3();

int main()
{
    system("clear");
    cout <<"\nVesikuusi Words 1.0\n\n";
    sleep(1);
    arvo();
    switch (x)
    {
    case 1: tekija = "Rölli ";
    break;
    case 2: tekija = "Rotta ";
    break;
    case 3: tekija = "Hitler ";
    break;
    case 4: tekija = "Jeesus ";
    break;
    case 5 :tekija = "Joukupukki ";
    break;
    default: main();
    }

arvo2();

switch (y)
{
case 1: verbi = "kusee ";
break;
case 2: verbi = "kurkkii ";
break;
case 3: verbi = "dokaa ";
break;
case 4: verbi = "myy joulukuusia ";
break;
case 5: verbi = "syö muurahaisia ";
break;
default: main();
}

arvo3();

switch (z)
{
case 1: paikka = "torilla.";
break;
case 2: paikka = "Saharalla.";
break;
case 3: paikka = "Kampissa.";
break;
case 4: paikka = "kaivossa.";
break;
case 5: paikka = "eteisessä.";
default: main();
}

print();
}
void arvo()
{
    srand(time(0));
    x=rand() % 5+1;
}

void print()
{
    cout <<tekija <<verbi <<paikka;
    cin.get();
    cout <<"\n\nUudestaan? K/E ";
    cin >>valinta;

    switch (valinta)
    {
    case 'k': case 'K': system("clear"); main();
    break;
    case 'e': case 'E': system("clear"); exit(0);
    default: main();
    }
}

void arvo2()
{
   srand(time(0));
   y=rand() % 5+1;
}

void arvo3()
{
    srand(time(0));
    z=rand() % 5+1;
}

Grez [10.02.2011 15:26:28]

#

Kutsu srand vain kerran.

vesikuusi [10.02.2011 15:28:49]

#

kiitos paljon! Homma pelittää :D

Mizou [10.02.2011 17:27:46]

#

Pieni kirjoitusvirhe luultavasti?

case 5 :tekija = "Joukupukki ";

:)

eq [10.02.2011 18:23:31]

#

Ohjelma on virheellinen. C++ ei salli main-funktion käyttämistä (standardin määrittelemällä tavalla "käyttäminen") ohjelman sisällä; toisin sanoen, main-funktiota ei saa (mm.) kutsua rekursiivisesti. Suosittelen säätämään kääntäjän varoitustason suuremmalle, ja hankkimaan hyvän C++-kirjan aloittelijoille oppimista varten.

(Ohjelman rakenne ei ole kehuttava muutenkaan.)

Teuro [12.02.2011 12:30:22]

#

Tässä eräs toteutus tuosta tehtävästä. Ihan paras mahdollinen tämäkään ei ole.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>

// satunnaisen numeron arposeen saa parametrinä
// kaksi lukua, joiden väliin numero osuu
int arvo_numero(int ala, int yla);

// lauseen rakenne ei täydellinen, mutta sopiva tarkoitukseen
struct lause {
	// Lauseen osien säilytyspaikat jokaiselle oma
	std::vector <std::string> tekijat;
	std::vector <std::string> paikat;
	std::vector <std::string> verbit;

	// Tulostettava lause
	std::string generoitu_lause;

	// Generoi lauseen kolmesta osasta
	void generoi_lause();
	// Sanat ovat tiedostossa, josta ne noudetaan säilytyspaikkoihin
	void hae_sanat(std::string tiedosto);
	// Palautetaan generoitu lause
	std::string palauta_generoitu_lause();
};

int main() {
	std::cout <<"Vesikuusi Words 1.0" << std::endl;

	// Käyttäjän valinta jatkolle
	std::string valinta = "e";

	// do - while looppi kierretään kunnes käyttäjä antaa muun kuin K tai k
	do {
		// Uusi lause
		lause tmp;
		// Tulostetaan katso logista funktioiden kutsu järjestys
		std::cout << tmp.palauta_generoitu_lause() << std::endl;

		//Kysytään vieläjkö generoidaan
		std::cout << "Uudelleen? K tai E" << std::endl;
		std::cin >> valinta;
	} while (valinta == "K" || valinta == "k");

	// Onnistui
	return 0;
}

void lause::hae_sanat(std::string tiedosto) {
	std::clog << "lause::hae_sanat(" << tiedosto << ")" << std::endl;

	std::ifstream sisaan("sanat.txt", std::ios::in);
	std::string sana;
	int kontti;
	std::srand(std::time(NULL));

	while (sisaan >> sana) {
		if (sana == "Paikat:") {
			kontti = 1;
			continue;
		} else if (sana == "Tekijat:") {
			kontti = 2;
			continue;
		} else if( sana == "Verbit:") {
			kontti = 3;
			continue;
		} else {
			if (kontti == 1) {
				paikat.push_back(sana);
			} else if (kontti == 2) {
				tekijat.push_back(sana);
			} else if (kontti == 3) {
				verbit.push_back(sana);
			}
		}
	}
}

void lause::generoi_lause() {
	std::clog << "lause::generoi_lause()" << std::endl;

	this->generoitu_lause += tekijat[arvo_numero(0, tekijat.size())];
	this->generoitu_lause += " ";
	this->generoitu_lause += verbit[arvo_numero(0, verbit.size())];
	this->generoitu_lause += " ";
	this->generoitu_lause += paikat[arvo_numero(0, paikat.size())];
}

std::string lause::palauta_generoitu_lause() {
	std::clog << "lause::palauta_generoitu_lause()" << std::endl;
	hae_sanat("sanat.txt");
	generoi_lause();

	return generoitu_lause;
}

int arvo_numero(int ala, int yla) {
    return (ala + rand()  % (ala + yla));
}

Teuro [12.02.2011 14:07:47]

#

Kas vain jäi vielä tuon tiedoston formaatti näyttämättä, joskin sen voi varmaankin päätellä aika helpolla.

Tekijat:
Joulupukki
Jesse
Pelle
Paikat:
Saharassa
Kiinassa
Suomessa
Verbit:
Hölkkää
Juoksee
Suunnistaa
Aivastaa

vesikuusi [12.02.2011 22:45:40]

#

Teuro kirjoitti:

Tässä eräs toteutus tuosta tehtävästä. Ihan paras mahdollinen tämäkään ei ole.

Juuh, miä oon vasta aika alottelija, peruskoulu vasta loppuu tossa kevääl..mutta kiitosta vaan :D


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta