Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Tietojen tallentaminen tiedostoon

Sivun loppuun

Zmyrgel [16.10.2005 11:28:58]

#

Olen kokeillut etsiä jotain toimivaa ja sopivan yksinkertaista tapaa tallentaa tietoja tietuetaulukosta tiedostoon. Parin kokeilun jälkeen olen saanut aina tämän tyyppisiä virheitä:
"'cout' : ambiguous symbol", sama cin, cerr yms. Mistä tälläiset johtuu?

http://tiira.cedunet.com/~jtahka/oppim/ohjelmointi/c /monist85.htm

Tuolta löytynyttä esimerkkiä soveltaen ilmenee ko. virheet. Katselin täältä keskusteluista löytyneitä esimerkkejä mutta ne on hieman haastavia tarkasteltavaksi ilman kommentteja.

sqwiik [16.10.2005 11:47:09]

#

Hmm. Millaista tietuetta olet tallentamassa?

Zmyrgel [16.10.2005 12:34:57]

#

#define tiedosto "save.cdb";
ofstream taltio;       //esitellään tietovirtalio

void tallenna(void)
{
	int k = 0;
		//avataan tiedosto kirjoittamista varten
		taltio.open(tiedosto, ios::out);
		//tarkistetaan onnistuiko avaus,
		//osoitin 0 jos avaus ei onnistunut
		if(!taltio){
			cerr << "Tiedostoa " << tiedosto;
				  << "ei voinut avata !" << endl;
			exit(1);     //poistutaan ohjemasta, vaatii <stdlib.h>:n
		}
			for (k=0;k<counter;k++)
			{
				taltio << tietokanta[k].merkki << ' ' << tietokanta[k].malli << ' ' << tietokanta[k].vuosimalli << endl;
			}
		taltio.close();
}

Tuollainen nopeasti kyhätty tekele. Tietokanta on globaali tietuetaulukko.

Metabolix [16.10.2005 12:54:26]

#

Otapa ensiksi define-rivin perästä puolipiste pois. Se kun ei ole C++:aa vaan esikääntäjän tekstiä.

Nyt koko homma kaatuu siihen, että jos jokin kirjoitettavista tiedosta sisältää välin, et enää tiedä, missä menee merkin ja mallin raja. Käytä siis binäärimuotoista tallennusta.

Ja koodin voisi sisentää ymmärrettävästikin.

Meitsi [16.10.2005 13:05:05]

#

Ja tuossa on tuo exit funktio joka vaatii sen stdlib:in jota tuossa ei ole includettu.

Ja pistäppä tuonne alkuun

using namespace std;

Zmyrgel [16.10.2005 13:08:19]

#

Meitsi kirjoitti:

Ja tuossa on tuo exit funktio joka vaatii sen stdlib:in jota tuossa ei ole includettu.

Ja pistäppä tuonne alkuun

using namespace std;

Joo, no tuo on vain ohjelman yksi aliohjelma. stdlib.h on sisällytetty ja nimiavaruuskin on käytössä.

Metabolix kirjoitti:

Otapa ensiksi define-rivin perästä puolipiste pois. Se kun ei ole C++:aa vaan esikääntäjän tekstiä.

Kappas, en muistanutkaan tuota.

lainaus:

Nyt koko homma kaatuu siihen, että jos jokin kirjoitettavista tiedosta sisältää välin, et enää tiedä, missä menee merkin ja mallin raja. Käytä siis binäärimuotoista tallennusta.

Tietoja syöttäessä tarkistetaan ettei tule välilyöntejä (kokeilin ja totesin ettei toimi 100%)

lainaus:

Ja koodin voisi sisentää ymmärrettävästikin.

Tuo nyt oli tuollein nopeasti kyhätty.

Zmyrgel [16.10.2005 23:09:59]

#

void tallenna(void)
{
	char * buffer;
	long size;
	ifstream file (filename, ios::out|ios::binary|ios::trunc); //<-Kirjoitetaan binäärimuoteisena ja poistetaan jos tiedosto on jo olemassa
	size = file.tellg();
	file.seekg (0, ios::beg);
	buffer = new char [size];
	file.read (buffer, size);
	file.close();

	cout << "the complete file is in a buffer";

	delete[] buffer;
}

Tälläinen koodipätkä on nyt kasassa. Miten tällä pystyy tulostamaan tiedostoon tietuetaulukon sisällön?

Zmyrgel [17.10.2005 11:11:07]

#

No niin, sain tallenna funktion toimimaan mutta nyt ohjelma kaatuu jostain syystä lataa funktioon. Ohjelman tarkoituksena on ladata vanhat tiedot tiedostosta aina ohjelma käynnistyessä ja tallentaa muutokset suljettaessa ohjelma. Mitään virheilmoitusta ohjelma ei anna vaan kääntää sorsan hyvin.

edit: Virhe löytyi strcat -kohdasta. Voisiko joku valaista miksi se kaatuu siihen?

void lataa(void)
{
	int tapa = 1;
	int i = 0;
	int pituus = 0;
	int laskuri = 0;
	char temp[512] = "";
	char merkki;
    int k = 0;
	ifstream iFile(tiedosto);
        //avataan tiedosto kirjoittamista varten
        //tarkistetaan onnistuiko avaus
        if(!iFile){

            cerr << "Tiedostoa " << tiedosto << "ei voinut avata !" << endl;
            exit(EXIT_FAILURE);
        }
    do{	//Käydään tiedosto läpi merkki kerrallaan ja sijoitetaan merkki temp muuttujaan
		iFile.get(merkki);
		strcat(temp, &merkki); //<- CIRHE ON TÄSSÄ. AIHEUTTAA OHJELMAN KAATUMISEN
			if (merkki=='\n'){ //Rivin vaihdon sattuessa sijoitetaan tempin sisältö taulukkoon
				pituus = strlen(temp);
					for(i=0;i<pituus;i++){
						switch(tapa){
						case 1:
							tietokanta[laskuri].merkki[i] = temp[i];
							break;
						case 2:
							tietokanta[laskuri].malli[i] = temp[i];
							break;
						case 3:
							tietokanta[laskuri].vuosimalli[i] = temp[i];
							break;
						default:
							cout << "Ohjelmassa sattui virhe ja se lopetetaan!";
								exit(EXIT_FAILURE);
							break;
						}
						if(temp[i]=='_')//Tallennus tekee '_'-merkin välilyöntien paikalle
							tapa++;
					}
					for(i=0;i<512;i++){ //Tyhjennetään temp muuttuja ennen uutta riviä
						temp[i] = 0;
					}
			laskuri++; //Siirrytään seuraavaan taulukon alkioon
			}
	}while(!iFile.eof());
        iFile.close();
}

Meitsi [17.10.2005 11:19:23]

#

Tulosta joka välissä konsoliin, mitä teet. Se helpottaa debuggausta olennaisesti.

Deewiant [17.10.2005 16:01:51]

#

Mutua: strcat ottaa parametreikseen nollatavuihin loppuvat stringit, mutta annat sille yksittäisen merkin. Se sitten yrittää lukea tuosta merkistä muistia eteenpäin, kunnes käyttis päättää, ettei se enää käy, ja kaataa ohjelman.

Zmyrgel [18.10.2005 12:18:16]

#

Kiitoksia tuosta konsoliin tulostamisesta. Ei tullut mieleen itselle ja auttoi kivasti eteenpäin. Nyt sain ohjelman lukemaan tiedostoa rivi kerrallaan mutta se ei osaa laittaa sitä oikeaan järjestykseen:

    do{	//Käydään tiedosto läpi rivi kerrallaan ja sijoitetaan rivi temp muuttujaan
		iFile.getline (temp, 512);// Luetaan rivi tiedostosta temp muuttujaan  "fiat_brava_2004\n"
			pituus = strlen(temp);
				cout << temp << endl; //DEBUG
			for(i=0;i<pituus;i++){		//Sijoitetaan tempin sisältö tietokantaan
					switch(tapa){
						case 1:
							if(temp[i]=='_'){
								tapa++; //Jos tulee '_'-merkkin niin siirrytään seuraavaan temp alkioon ja sijoitetaan                                      tulevat arvot malliin.
								break;
							}
							else{
								tietokanta[counter].merkki[i] = temp[i];
								break;
							}
						case 2:
							if(temp[i]=='_'){
								tapa++;
								break;
                            }
							else{
								tietokanta[counter].malli[i] = temp[i];
								break;
							}
						case 3:
							tietokanta[counter].vuosimalli[i] = temp[i];
							break;
						default:
							cout << "Ohjelmassa sattui virhe";
							break;
					}
			}
		counter++;
		tapa = 1;
	}while(!iFile.eof());

tiedostossa olevat tiedot ovat esim: fiat_brava_1993\nford_focus_2001 jne. Ohjelma sijoittaa .merkkiin tiedot mutta ei syötä kahteen myöhempään mitään.

Mazuli [19.10.2005 14:25:06]

#

eikä olisi helpompaa käyttää c:n functioita fwrite ja fread
esim.

/* auto tietue */

typedef struct auto
{
  char *merkki;
  char *malli;
  char *vuosi;
};

/* tietokanta taulu */

auto tietokanta[2];

/* asetetaan jotain arvoja */

tietokanta[0].merkki = "Ford";
tietokanta[0].malli  = "Mondeo";
tietokanta[0].vuosi  = "2005";

tietokanta[1].merkki = "Peugeot";
tietokanta[1].malli  = "406";
tietokanta[1].vuosi  = "2000";

/* tallennetaa tietokanta */

FILE *fp = fopen("tietokanta.db", "w");

fwrite(tietokanta, sizeof(tietokanta), 1, fp);
fclose(fp);

/* sitten kun haluat lukea */

auto tietokanta[2];

FILE *fp = fopen("tietokanta.db", "r");

fread(&tietokanta, sizeof(auto), 2, fp);
fclose(fp);

Metabolix [19.10.2005 20:40:33]

#

Eihän tuo Mazulin koodi voi toimia. typedef ei toimi noin, eikä tuollaista arvojen asettelua voi käyttää. Tiedostoon ei myöskään tulostu mitään tekstiarvoja, vaan se osoitin, ja siitäpä ei olekaan mitään iloa kenellekään. Kannattaisi testata, ennen kuin laittaa esimerkkiä.

Ongelmasi on siinä, että kun törmäät alaviivaan, esimerkiksi i = 10, jatkat kirjoittamista seuraavaan kohtaan kohdasta 10 etkä alusta. Siksi pitäisi tehdä tähän tapaan:

int i, j;
// ...
for (i = j = 0; i < pituus; i++, j++) // huom. j
// ...
if (temp[i] == '_') {
  tietokanta[counter].merkki[j] = 0; // Muista lopetusmerkit tauluihin!!!
  j = -1; // ja seuraavan kierroksen alussa se on taas 0, eli kirjoitus alkaa seuraavan taulun alusta
}
// ...
tietokanta[counter].merkki[j] = temp[i]; // Näissä se j käyttöön

Tuossa siis ideoita, saat itse lisäillä ja muutella ne koodiisi.

Suosittelen for-silmukoiden kirjoittamista selkeämpään muotoon, ettei tarvitse etsiä puolipisteitä siitä epämääräisestä merkkipötköstä.

switch-systeeminkin voi kirjoittaa vähän vähemmillä breakeilla, kun siirtää ne if- ja else-palikoiden ulkopuolelle. Koodikin selkenee ihmeesti.

Toinen hyvä tapa tähän olisi laittaa kaikki erikseen (tulee peräti paljon vähemmän koodia):

for (i = j = 0; i < pituus && temp[i] != '_'; i++, j++)
  tietokanta[counter].merkki[j] = temp[i];
tietokanta[counter].merkki[j] = 0;

for (j = 0; i < pituus && temp[i] != '_'; i++, j++)
  tietokanta[counter].malli[j] = temp[i];
tietokanta[counter].malli[j] = 0;

for (j = 0; i < pituus; i++, j++)
  tietokanta[counter].vuosimalli[j] = temp[i];
tietokanta[counter].vuosimalli[j] = 0;

Zmyrgel [19.10.2005 21:57:24]

#

Joo, nyt se tallentaa vielä aina lopettaessa kaksi alaviivaa tiedostoon mitä pitää tuumailla. Samoin virheentarkistus muissa funktiossa. Sitten varmaan käyn optimoimaan näitä/ opettelemaan optimoimaan näitä. Mutta kiitokset avusta.

Zmyrgel [20.10.2005 12:56:32]

#

Tälläinen ongelma on muodostunut. Pitäisi saada ohjelma tulostamaan tiedot siististi käyttäjälle ja ajattelin että tämä hoituu kätevästi sijoittamalla tietokannan sisällön string muuttujaan tähän malliin:
string esitys = .merkki
sitten stringin 20. alkiosta eteenpäin se tulostaa .mallin ja 40. eteenpäin tulostaa .vuosimallin. Välissä olevat merkit ovat tyhjiä. Lopuksi tämä stringi tulostetaan käyttäjälle.

Ongelmana on stringiin sijoittaminen. Miten tämä onnistuisi kätevästi?

string esitys = "";

esitys.data(); //Palautettaan osoitin stringin alkuun
esitys = tietokanta[y].merkki; //Stringin alussa on .merkki
esitys.at[20] = tietokanta[y].malli; //Virhe, ei toimi. 20. merkistä eteenpäin .malli
esitys.at[30] = tietokanta[y].vuosimalli; //Virhe, ei toimi 30. merkistä eteenpäin .vuosimalli
cout << esitys << endl; //Tulostetaan käyttäjälle
esitys.clear(); //Tyhjennetään stringi

Aruviel [20.10.2005 16:02:28]

#

Metodi at on string-luokkaan kuuluva. Elä käytä hakasulkeita. Sitä paitsi at-metodi ei toimi noin.

The at() function returns a reference to the element in the string at index loc. The at() function is safer than the [] operator, because it won't let you reference items outside the bounds of the string.

Lähde: http://cppreference.com/cppstring/at.html

Varmaankin kannattaa muuttaa esitys-olion kokoa resize-metodilla luonnin jälkeen. Tämän jälkeen sijoitat merkkisi kohtaan [0]. Ja resizella onnistuu noitten tyhjien merkkien asettaminen kätevästi.

string temp="";
temp.resize(20,' ');
cout << temp.size(); // näyttää nyt 20, jokainen alkio sisältää merkin ' '.
temp += "Tää tulee tyhjien merkkien perään.";

http://cppreference.com/cppstring/

Zmyrgel [20.10.2005 17:42:22]

#

Seuraava kysymys mitä mietin koskee tiedostosta lukemista. Copy-Pastesin netistä listan missä näkyy auton malli, valmistaja ja vuosiluvut milloin ko. merkkiä tehty. Nyt pyrkisin käyttämään tätä työssäni avuksi selvittämään onko syötetty merkki/malli oikea. Tiedot on tallennettu tiedostoon tälläiseen ulkoasuun(eroaa omasta näkymästä):

Cab-Chassis Ford 88 89 90
Caballero GMC 85 86 87
Cabrio Volkswagen 95 96 97 98 99 00 01 02
Cabrio Yugo 90 91


Tiedot on kopioitu täältä notepadiin: http://www.kbb.com/kb/ki.dll/kw.kc.mn?kbb&&108&u

1) Näkeekö mistään mikä merkkejä mallin ja merkin välillä on? \t siinä on mutta onko se kahteen kertaan vai \n + \t.

2) Ohjelma pätkä joka lukee auton valmistajan tiedostosta ja listaa ne käyttäjälle joka voi näistä valita merkin. Tämän perusteella ohjelma listaa sitten ko. merkin mallit ja viimeiseksi vuodet milloin mallia tehty.


Aika simppeli hommahan tuo on loppupeleissä. Apua tarvitsen näin aluksi tuon tiedoston lukemisessa / käsittelyssä. Muuten uskoisin saavani itse hoidettua loppuun. Eli miten saan luettua tuollaisesta syötteestä esim merkin?

iFile.getline (temp, 512);

Tällä se varmaan lähtee liikenteeseen. Tuosta pitäisi tabuloinnit ja muu turha saada pois.

Metabolix [20.10.2005 19:16:37]

#

Ei välttämättä ole hyvä käyttää tuota getline-funktiota, kun ei voi tietää, jos rivi vaikka olisi pidempi. (Eihän se yleensä ole, mutta kuitenkin.) Tai ainakin pitää muistaa, ettei se välttämättä ole koko totuus. Minä edelleenkin lukisin tiedostoa binäärimuodossa pala kerrallaan ja käsittelisin sitä niin. Silloin on helpointa tehdä mitä tahansa.

Tässä esimerkki turhien poistosta:

void Poista_Turhat(char * Teksti, char * UusiTeksti, int Turhien_Maara, char * Turhat)
{
  int i, j, k, Siirrytaan;
  for (i = j = 0; Teksti[i] != 0; i++)
  {
    Siirrytaan = 0;

    // Käydään läpi kaikki ei-halutut merkit
    for (k = 0; k < Turhien_Maara; k++)
    {
      // Onko tämä sellainen?
      if (Teksti[i] == Turhat[k])
      {
        // Merkitään, että siirrytään, ja mennään pois tarkistussilmukasta
        Siirrytaan = 1;
        break;
      }
    }

    // Jos vääriä löytyi, mennään seuraavaan merkkiin
    if (Siirrytaan)
      continue;

    // Muuten laitetaan merkki uuteen tekstiin kohdalleen
    UusiTeksti[j] = Teksti[i];
    j++;
  }
  UusiTeksti[j] = 0;
}

// Esimerkki:
char Ei_Naita[] = ":\t)äln";
int Turhia = 6;
char Teksti[] = "Erkki-ritari on apina! Sillä on iso nenä\t\t:)";
char Sensuroitu[100];

Poista_Turhat(Teksti, Sensuroitu, Turhia, Ei_Naita);
// Sensuroitu = "Erkki-ritari o apia! Si o iso e";

Tuosta saat varmaan helposti tehtyä sellaisen, joka poistaa peräkkäiset tietyt merkit.

Zmyrgel [22.10.2005 10:25:58]

#

Kiitokset edellisestä koodista. Tuosta oli huomattava apu. Tein ohjelman joka muokkasi tiedoston sisällön hieman luettavampaan muotoon.

Käytetään nyt tätä ketjua apuna...

switch(syote){
			for (i = 0; i < laskuri + 1; i++)
			{
			case i:
				for (k = 0; k<strlen(ehto[i].malli); k++)
				{
					tietokanta[counter].malli = ehto[i-1].malli;
				}
				break;
			}
		}

Tälläinen koodipätkä. Switch ei huoli tuollaista case rakennetta että ne tulostettaisiin for-silmukalla vaan niiden pitäsi olla vakiot. Onko mitään kiertotietä tähän?

sqwiik [22.10.2005 10:51:28]

#

Zmyrgel: switch-rakenteen case-lauseiden arvojen tulee olla vakioita. Ehdotan, että tuollaisessa tapauksessa teet tuon yksinkertaisesti if-lauseilla. Sitpä paitsi, mihin tuossa edes tarvitaan switch:iä?

Ja toisekseen, koodissasi on lause ehto[i - 1].malli. Entäs jos i = 0? Silloin tuo koodi osoittaa minne sattuu :/ Parhaimmillaan kaataa koko ohjelman.

Niin, ja mihin tuota k-silmukkaa tarvitaan? Tällä hetkellä se ainakin suorittaa strlen() kertaa saman, muuttumattoman lausekkeen jossa k:ta ei edes käytetä:

tietokanta[counter].malli = ehto[i-1].malli;

Eli sen silmukan voisi kait jättää pois. Ellei sen sitten ollut tarkoitus kopioida merkkijonoa?

tietokanta[counter].malli[k] = ehto[i].malli[k];

Zmyrgel [22.10.2005 11:14:39]

#

Joo, k:ta tarvitaan merkkijonon kopioimiseen. Se nähtävästi unohtu laittaa tuohon malliin. Hyvä pointti tuon i:n suhteen. En huomannutkaan sitä kun nopeesti kyhäsin tätäkin pätkää.
Pitää toteuttaa tämä sitten if-lauseilla.

Switchin tarkoitus olisi että aluksi ennen sitä ohjelma listaa auton mallit (vaihtelevia määriä... ford 37kpl audi 8 kpl jne.) Ja sitten switch silmukan perusteella sijoitetaan ehto tietueessa juuri sen alkion kohdalla oleva malli tietokantaan.

Metabolix [22.10.2005 11:20:55]

#

Muokataanpa tuo aiempi koodisi järkevään muotoon...

lainaus:

switch(syote){
            for (i = 0; i < laskuri + 1; i++)
            {
            case i:
                // Tähänhän siis päästään, jos (syote == i) ja (i < laskuri + 1)
                for (k = 0; k<strlen(ehto[i].malli); k++)
                {
                    // Täällä pitäisi kai olla molemmissa ".malli[k]"
                    tietokanta[counter].malli = ehto[i-1].malli;
                }
                break;
            }
        }

Sama selkeämmin (ja toimivasti):

if (syote < laskuri + 1)
{
  /* Huom seuraavassa "+ 1", jotta myös tekstin
  * lopetusmerkki tulee mukaan. Se ei kuulu pituuteen.
  * Tietenkin jos olet hoitanut sen jotenkin muuten,
  * niin voit toki käyttää omaakin tapaasi. */
  for (k = 0; k < strlen(ehto[syote].malli) + 1; k++)
  {
    tietokanta[counter].malli[k] = ehto[syote-1].malli[k];
  }
}

Ja todennäköisesti tehokkaammin:

if (syote < laskuri + 1)
{
  // string.h:sta löytyvä muistinkopiointifunktio.
  // memcpy(lähdeosoitin, kohdeosoitin, pituus)
  memcpy(tietokanta[counter].malli, ehto[syote-1].malli, strlen(ehto[syote].malli) + 1);
}

Zmyrgel [23.10.2005 13:54:17]

#

Tälläinen ongelma:
Jos syötän jonkin arvon seuraavaan koodi pätkään ni se ajaa switch-lauseen kahteen kertaan. Esim jos valitsee 1. niin se menee kysy-funktioon mutta siellä kun se kysyy automerkkiä niin se antaa siihen vielä tyhjän arvon. Sama jos antaa 2. niin se tulostaa tiedot kahteen kertaan. Ensimmäisellä kerralla se tulostaa oikein ja jälkimmäisellä kerralla se valittaa että Virheellinen syöte!. Mistä ko. asia johtuu?

int main()
{
lataa();	//Ladataan tallennetut tiedot
	while(1){
		char syote = NULL;
		cout << "\nMit\x84 haluat tehd\x84?\n\t1)Anna uusi tietue\n\t2)Tulosta annetut tiedot\n\t3)Lopeta ohjelma\n";
		cin.get(syote);
			switch(atoi(&syote)){
				case 1:
					kysy(counter);
					counter++;
					break;
				case 2:
					jarjesta(tietokanta, counter);
					tulosta(counter);
					break;
				case 3:
					if (tietokanta[0].merkki == "")
						exit(EXIT_SUCCESS);
					else
						tallenna();
						exit(EXIT_SUCCESS);
					break;
				default:
					cout << "Virheellinen Sy\x94te!\n";
					break;
			}
	};

return 0;
}

Metabolix [23.10.2005 15:24:49]

#

3. case kaipaa aaltosulkuja else-blokkiin. Nyt exit-funktio suoritetaan ehdosta riippumatta. Pelkkä sisennys ei C:ssä auta :)

atoi ei myöskään toimi tuossa oikein. (Tai siis jos toimii, niin se on vain hyvää tuuria.) Sille pitää antaa char-taulu (eli -osoitin), jonka lopussa on 0-merkki. Muutenkin itoa on tuossa aivan turha.

switch (syote)
{
case '1':
  // jne.

Zmyrgel [24.10.2005 10:01:49]

#

lainaus:

3. case kaipaa aaltosulkuja else-blokkiin. Nyt exit-funktio suoritetaan ehdosta riippumatta. Pelkkä sisennys ei C:ssä auta :)

:) Sen on tarkoituskin poistua ohjelmasta. Se vaan jättää tallentamatta jos tietokannassa ei ole tietueita. (tallentaa/tallenti tyhjän rivin tiedostoon). Korjasin että switch-lauseen antamaasi muotoon ja syote on tyyppia char. Vieläkin tosin ohjelma suorittaa annetun vaihtoehdon kahteen kertaan. Se menee tietoja tulostaessa tuonne tulosta funktioon ja suorittaa sen oikein ja palaa alkuvalikkoon mutta antaa alkuvalikossa tyhjän syötteen josta ohjelma valittaa. Sama ekaan vaihtoehtoon, kysyttäessä automerkkiä ohjelma antaa tyhjän syötteen automaattisesti cin.getlineen ja kiertää silmukan kertaalleen läpi ennen kuin antaa käyttäjälle mahdollisuuden antaa mitään syötettä.

Metabolix [24.10.2005 12:15:11]

#

Se jälkimmäinen syöte, jonka saat, on enter. Kannattaisi varmaankin käyttää tuossa kaikesta huolimatta int-muuttujaa ja lukea cin:stä >>-operaattorilla jokin luku. Siitähän täällä on jo annetta vaikka miten paljon ohjeita ihan virheentarkastuksineen kaikkineen.

EgE915 [31.10.2005 17:46:25]

#

öh, miten voin tallentaa pelkkää tekstiä tekstitiedostoon?
esim. jos haluan tallentaa annetun lauseen tiedostoon koe.txt? tai miten tallennetaan muunlaisiin tiedostoihin, kuten .dat tiedostoihin? (tällainen noppa kysymys, muttei opi jossei kysy :P)

rndprogy [31.10.2005 18:25:43]

#

EgE915 kirjoitti:

miten tallennetaan muunlaisiin tiedostoihin, kuten .dat tiedostoihin?

Se ei ole tiedoston "tyypistä"/päätteestä kiinni. Ihan normaalisti merkkejä merkin perään sinne joka tapauksessa tallennetaan :P

Metabolix [31.10.2005 21:29:17]

#

Jos ei ole aavistustakaan, niin silloin pitää lukea jokin opas. Ei ole käytännöllistä, jos jokaiselle aloittelijalle pitää henkilökohtaisesti opettaa tiedostojen käyttö.


Sivun alkuun

Vastaus

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

Tietoa sivustosta