Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Merkkijonotaulukot

Sivun loppuun

hunajavohveli [09.05.2004 19:04:07]

#

Haluaisin määritellä taulukon, jonka eri alkioihin voisi tallentaa merkkijonoja, mutta ongelmana on se, että merkkijono on jo valmiiksi taulukko, jossa jokainen alkio käsittää yhden merkin. Tein sitten näin:

char taulukko[20][10];

Tarkoitus on siis luoda taulukko, johon mahtuu 10 merkkijonoa, joiden maksimipituus on 20 merkkiä. Noita vain tuntuu olevan hemmetin vaikea käsitellä.

taulukko[0][0] = "tekstiä";    //ei tietenkään toimi
taulukko[0] = "tekstiä";    //kaiken logiikan mukaan ei tietysti tämäkään

taulukko[0][0] = "t";
taulukko[0][1] = "e";
taulukko[0][2] = "k";
taulukko[0][3] = "s";
taulukko[0][4] = "t";
taulukko[0][5] = "i";
taulukko[0][6] = "ä";

Onko viimeinen keino ainoa tapa tehdä tuo? Saisihan tuosta kai tehtyä oman funktionkin, joka hoitaisi asian yhdellä käskyllä.

Aruviel [09.05.2004 19:34:55]

#

En ole mikään hyvä, ja en tiedä miten tuossa käy, että alkaako se osoittelemaan minne sattuu kun noita lisää. Alussa se ainakin kannattaisi alustaa NULLilla, luulisin ;P.

#include <stdio.h>

int main(void)
{
  char* taulu[10];

  taulu[0] = "Terppa!";
  taulu[1] = "No moi sullekin, taulu0!";

  printf("%s \n %s",taulu[0],taulu[1]);


  return 0;
}

Joku viisampi osaa sanoa minua paremmin. Ja tosiaan, maksimipituutta sinun pitää jotenkin muuten rajoittaa.

jv_windy [10.05.2004 14:09:32]

#

C-kielessähän merkkijonon sijoittamisella char-taulukkoon ei olisi olisi ongelmia, mutta C++:n nykyisen stantardin mukaan tämä ei kelpaa.

Aruviel:n tapa toimii, mutta tällöin et voi rajoittaa maksimipituutta.

Alustaminen kyllä onnistuu:

char taulukko[10][20] = {"Eka", "Toka", "Kolmas"};

Tämä siis luo 10 merkkijonotaulukkoa, joihin mahtuu 20 merkkiä (sisältäen null), omassa koodissasi oli tämä väärinpäin.

Mutta sijoittaminen ei C++:ssa onnistu samalla tyylillä. Jos haluat käyttää char-taulukoita, sijoitus kaksiulotteiseen taulukkoon tapahtuu näin:

char taulukko[10][20];
strcpy(taulukko[0], "tekstiä");
strncpy(taulukko[0], "tekstiä", sizeof(taulukko[0]) - 1);
// yllä oleva parempi koska ylisuurta tietomäärää ei pystytä laittamaan muuttujaan vahingossakaan

Paras tapa, ja C++:ssa suositeltavin on käyttää uutta string-tyyppiä:

string taulukko[20];
taulukko[0] = "Tekstiä";
taulukko[1] = "Tekstiä 2";

Edit: Siirsin kommentin omalle rivilleen, koska muuten sivu leveni sen takia.

Edit2: Tarvitset vielä tietenkin "#include <string>"-rivin esikäsittelijälle.

hunajavohveli [10.05.2004 15:00:15]

#

Ai tuollainen string-tyyppikin on olemassa. Sitä en tiennytkään, mutta nytpähän tiedän. Kiitos!

Edit: Mutta minulla on edelleen ongelma. Cout nimittäin jostain kumman syystä tulostaa noita string tyypin muuttujia aina siihen kohtaan, missä päähenkilö pelissäni on. Vaikka pistän eteen gotoxy(1,1); niin siitä huolimatta string-muuttujan sisältämä sana tulostuu aina päähenkilön @-merkin eteen, vaikka sen kaiken järjen mukaan tulisi tulostua vasempaan yläkulmaan. Tulostan ihan normaalisti:

cout << WName[0];

Tuossa WName on siis string-tyypiksi määritelty muuttuja.

Dual [10.05.2004 17:22:34]

#

jv_windy kirjoitti:

Paras tapa, ja C++:ssa suositeltavin on käyttää uutta string-tyyppiä:

string taulukko[20];
taulukko[0] = "Tekstiä";
taulukko[1] = "Tekstiä 2";

Edit: Siirsin kommentin omalle rivilleen, koska muuten sivu leveni sen takia.

Edit2: Tarvitset vielä tietenkin "#include <string>"-rivin esikäsittelijälle.

Totta, mutta kaikista C++-kääntäjäpaketeista kyseistä headeriä ei löydy... vaan pitäisi se kuitenkin suht helposti googlettamalla löytyä.

hunajavohveli [10.05.2004 18:35:45]

#

Borlandissa tuo on onneksi jo valmiina. Ainakin ohjelma kääntyi ihan oikein, mutta osaatteko sanoa, mikä tuossa toisessa ongelmassani voisi olla vialla?

jv_windy [10.05.2004 20:58:52]

#

string-kirjasto on nykyään yleensä aina kääntäjän mukana, vanhempi tapa viitata siihen on string.h

hunajavohveli kirjoitti:

Cout nimittäin jostain kumman syystä tulostaa noita string tyypin muuttujia aina siihen kohtaan, missä päähenkilö pelissäni on. Vaikka pistän eteen gotoxy(1,1); niin siitä huolimatta string-muuttujan sisältämä sana tulostuu aina päähenkilön @-merkin eteen, vaikka sen kaiken järjen mukaan tulisi tulostua vasempaan yläkulmaan.

Kyllä tuo gotoxy minulla toimii. Tuo gotoxy(1,1):n pitäisi toimia, gotoxy(0,0) taas ei tee mitään. Toimiiko tuo gotoxy muka muuten, paitsi juuri string-muuttujia tulostettaessa? Ei minulla ainakaan ollut siinä ongelmia. Näytäpä koodiasi enemmän.

hunajavohveli [10.05.2004 21:50:47]

#

Tässä on kylläkin vain pieni osa koko koodista, mutta kokonaan se olisi vienyt aivan liikaa tilaa. Tässä on kuitenkin olennainen ja ongelma on edelleen sama.

Kuten huomaat, stringin headeri on mukana ja WName on määritelty string-tyyppiseksi. Merkitsin *-rivillä kohdan, jossa cout on. Kuten näet, sitä edeltää gotoxy(1,1), mutta kuitenkin WName[0], jonka arvo on siis "fists" tulostuu aina juuri ennen @-merkkiä, jota voit liikuttaa.

#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <string>


int x=1;     //set coordinates
int y=2;
int vx=1;
int vy=2;

int MHe=8;     //health
int He=MHe;


string WName[20];   //Weapon name
int WSta[20][10];    //Weapon stats
int Wi=0;          //Weapon-in-use index




void LoadWeapons(void)
{

 	WName[0] = "Fists";
   WName[1] = "Dagger";

	WSta[1][0] = 1;
   WSta[1][1] = 1;
   WSta[1][2] = 3;
}



void main(void)
{

	LoadWeapons();

	char NP[1];
   int a;


	do {                     //main game loop

      gotoxy(1,1); cout << "Health: " << He << " / " << MHe;
      gotoxy(20,1); cout << "Weapon: ";

      gotoxy(1,1);
      cout << WName[0];      //***************************************************

		gotoxy(x,y);         //draw main character
	   cout << "@";

	   a = getch();     //key system

   	gotoxy(x,y);        //fade main character
   	cout << " ";

   	vx = x;          //save coordinates
   	vy = y;

   	if (a == 54)        //move system
   		x++;
   	if (a == 52)
   		x--;
   	if (a == 53)
   		y++;
   	if (a == 56)
   		y--;


   } while (a!=27);       //esc ends

}

jv_windy [10.05.2004 22:44:53]

#

Minulla Fists tulostui kyllä ihan oikein vasempaan yläkulmaan. @-merkki ei liiku minulla.

Tosin gotoxy-funktioni on tällainen:

void gotoxy(int x, int y) {
  COORD c;

  c.X = x - 1;
  c.Y = y - 1;
  SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}

Nyt nukkumaan..

thefox [11.05.2004 11:58:30]

#

jv_windy kirjoitti:

C-kielessähän merkkijonon sijoittamisella char-taulukkoon ei olisi olisi ongelmia, mutta C++:n nykyisen stantardin mukaan tämä ei kelpaa.

Ei taida homma toimia C:lläkään yhtään sen paremmin, strcpy is the way to go.

hunajavohveli: on kai se ymmärrettävää että kun sekotetaan standardeja ja epästandardeja funktioita, homma ei aina toimi niinkuin voisi luulla. Voisit kokeilla käyttää printf:ää cout:n sijaan.

hunajavohveli [11.05.2004 14:50:07]

#

Tuota @-merkkiä pitäisi kyllä pystyä liikuttamaan numeronäppäimillä 4,6,5,8. Vaihdoin tuon printf:n coutin tilalle, ja nyt toimii. Kiitos.

Gaxx [19.05.2004 14:24:48]

#

Mikähän mulla vois olla pielessä kun kääntäjäni on DevCpp 4.9.8.0 ja tuollainen string.h tiedosto tuli sen mukana, mutta kääntäjä vaan valittaa, kun yritän määritellä string tyyppistä muuttujaa?

koodi on tällainen:

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

int main()
{
string moro;
moro = "Morkkeli kaikki!";
printf("%s", moro); // printataanko se tolla s:llä?
system("PAUSE");
return 0;
}

Ja se valittaa tälläistä tosta rivistä kun yritän määrittää string muuttujan(rivillä 7):

'string' undeclared(first use this function)

Edit: Sitten kumminkin, kun katson debuggerilla, minkä tyyppinen tuo rivillä 8 oleva moro muuttuja on, niin se näyttää, että se on string tyyppinen.

hunajavohveli [19.05.2004 16:41:31]

#

Mulla ei menny kääntäjästä läpi "string.h" vaan piti pistää pelkkä "string", vaikka tiedoston nimi oli "string.h". Kumma juttu. Kokeilepa ottaa h pois.

tn [19.05.2004 17:29:13]

#

-> Gaxx :
Laita sen "string"-tyypin tilalle "std::string" tai kirjoita include-määrittelyjen jälkeen rivi: "using namespace std;".

Gaxx [19.05.2004 18:17:01]

#

Jaaha... en ollu sitten aikasemmin törmänny tilanteeseen, jossa olisi ollut välttämätöntä käyttää nimiavaruuksia. No, homma hoitu tolla ja nyt toimii.
Sitten ilmaanti vielä yks juttu. Millä toi string tyyppinen muuttuja tulostetaan tolla printf() funktiolla?

thefox [26.05.2004 01:56:30]

#

Siinä oli muistaakseni metodi nimeltään c_str tai vastaava, joka palauttaa const char -pointterin.

Jaska [26.05.2004 22:58:56]

#

Paitsi että C/C++ -kielessä ei ole metodeja vaan c_str() on funktio.

Krank [27.05.2004 23:31:23]

#

Jaska kirjoitti:

Paitsi että C/C++ -kielessä ei ole metodeja vaan c_str() on funktio.

Metodin ja funktion erohan oli...??

Jaska [28.05.2004 08:02:06]

#

Ero on terminologiassa. C/C++ -kielessä puhutaan funktioista kun taas esim. Javassa puhutaan metodeista.

peran [28.05.2004 14:23:35]

#

Jaska se ei aivan niinkään ole, vaikka yleisesti onkin. Proseduurit ja funktiot ovat normaaleja kutsuja, ja metodit ovat luokan kutsuja.
C:ssä kaikki kutsut ovat siis funktioita ja proceduureja, kun taas C++:ssa voi olla myös metodeita, koska se on oliopohjainen viritelmä C:stä.
Java on puhtaasti oliopohjainen. koska kaikki kutsut on kiinnitetty johonkin luokkaan, joten kaikki kutsut on metodeja.
Pascalissa kaikki kutsut ovat funktioita ja proceduureja.
Delphi on taas Pascalin oliopohjainen viritelmä, joten siinä on myös molempia.
Joskus C++-kutsuista käytetään virheellisesti nimitystä funktio, vaikka ne olisivatkin metodeja, koska ne menevät helposti sekaisin.

kehno [05.06.2004 11:25:00]

#

itse kun ohjelmoin yritän selventää koodia sillä tavalla, että funktio palauttaa arvon (laskee jotain, tms.) eikä tee mitään muuta (ei muuta olion tilaa). Metodi taas voi muuttaa olion tilaa mutta ei palauta arvoa. Nämä kaksi asiaa kun erottaa tulee koodista selkeämpi.
Tokihan metodi voi palauttaa arvon, mutta en suosi sitä koska se tekee koodista sekavemman ja varsinkin jos luokkia on paljon.


Sivun alkuun

Vastaus

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

Tietoa sivustosta