Gå til innhold

bruke char [] til å lese tekststrenger


Anbefalte innlegg

Videoannonse
Annonse

definisjon og tilordningen må skje i samme setning

char navn[30]="bla";

char navn[]="bla";

 

andre måter er som du sier cin og

 

strcpy(navn,"bla"); //pass på overflyt

 

og

 

char navn[30]={'a', 'b', 'c'};

navn[0]='a';

navn[1]='b';

navn[2]='c';

 

det som vel er galt med navn="bla" er at du sier navn[0]="bla" og det blir feil (tror jeg). lenge siden jeg har drevet med c nå så ta det jeg sier med en klype salt :)

Lenke til kommentar

Vet ikke helt om jeg makter å forklare hvorfor det ikke går (bortsett fra å si at det er "ulovelig i følge standaren" ellernoe slik), men driver man først med C så gjør man i stedet noe slikt:

char* navn;
navn = "Ola";

 

(og driver man med C++ så bruker man std::string)

Endret av søpple
Lenke til kommentar

grunnen til at jeg har brukt char [] er at jeg vil ha noe slikt:

 

class Data

{

private:

int alder;

char navn[30];

//annen kode....

 

}

 

og så finne størrelsen på objektet med sizeof(Data). Hvis man gjør det med f.eks en string så blir vel ikke størrelsen riktig p.g.a at man ikke vet størrelsen på string.

Endret av frg
Lenke til kommentar

Det er viktig å ikke anta at noe ikke er -- hvis man ikke /vet/ at det ikke er. Like viktig som andre veien (Edit: eller egentlig synes jeg det er viktigere å vite hva man ikke vet, for da vet man hvor man skal gå) -- det er altså viktig å vite hva man ikke vet..

 

http://www.cppreference.com/cppstring/

 

..stol på meg når jeg sier at std::string kan brukes i så og si /alle/ sammenhenger.. ikke kast bort tid ved å bruke char* og char[] og lignenede! Spør deg selv (eller gjerne her) 10 000 ganger før du vurderer å bruke char*/char[] fremfor std::string ..

Endret av søpple
Lenke til kommentar

/* Bør kanskje advare om at denne forklaringen neppe er særlig forståelig for nybegynnere innen programmering, meningen er i alle fall å demystifisere forskjellen mellom arrays og pekere */

 

Kanskje ikke så rart at dette temaet skaper forvirring, siden arrays og pekere brukes om hverandre i C. Et array er faktisk en peker til et minneområde på stacken av en kjent størrelse, men du får ikke lov til å tilordne noen ny adresse til et array som du kan gjøre med pekere. F.eks:

char array[] = "et array av tegn";
char *str = "en peker til en konstant streng";
str = "en ny peker til en konstant streng"; /* str tilordnes på nytt */
str = array /* Kan også peke til et array */

Den første setningen instruerer kompilatoren til å sette av plass på stacken til teksten "et array", og du kan fritt endre hvert av tegnene i strengen. Den andre setningen oppretter en peker til en streng i read-only minne, dvs. at du bør ikke prøve deg på å endre enkelttegn i strengen :] Pekeren kan tilordnes en ny streng, dog. Dette er forvirrende, men husk at C er et gammelt språk, og opererer på et lavt nivå (designet for å implementere et operativsystem tross alt).

Lenke til kommentar

char navn[30];
navn = "Ola";

Husk på at navn er det samme som &navn[0], altså adressen til det første elementet i arrayet. Å sette adressen til det første elementet til "Ola" gir ikke mening. (Hvis du prøver å lage et array med heltall blir det tydeligere hvor lite mening det gir.) Det er akkurat det samme som at du ikke kan endre hva navn peker til (som A_N_K poengterer), bare sett fra et litt annet synspunkt.

 

 

Mens dette går jo bra:

cin >> navn;

Det er fordi (bl.a.) cin er overlastet til å kunne operere med C-strenger (altså char*-ere). Nok en gang, hvis du prøver med heltall fungerer det ikke:

int lottokupong[34];
cin >> lottokupong;

Lenke til kommentar
Hvorfor går det ikke å gjøre slik:

char navn[30];

navn = "Ola";

navn er et objekt. navn="Ola"; innebærer å kopiere "Ola" fra et sted i minnet og inn i minnet brukt av navn. Dette er en mer sammensatt operasjon som krever mer kode.

 

Bak cin >> navn skjuler det seg et bibliotek med kode som gjør den nødvendige operasjonen.

 

char *navn;
navn ="Ola";

Er annerledes. Her er navn en peker, og navn="Ola"; innebærer å kun endre pekeren til å peke på stedet i minnet der "Ola" befinner seg.

Lenke til kommentar

Et array ('navn' i dette tilfellet) er også en peker, men kompilatoren tillater ikke at du endrer verdien dens. En konstant peker til minne allokert på stacken ville oppføre seg bortimot likt (den ville vel bare gå ut av skop når funksjonen returnerer), bortsett fra at kompilatoren ikke ville vite størrelsen på det allokerte området.

 

F.eks:

char * const navn = alloca(5);
sprintf(navn, "lars");
navn[0] = 'm';
navn = "ola"; /* Ikke lov */

Lenke til kommentar

Takk for alle svar.

 

Hvis jeg skal erstatte char med string, hvordan skal jeg da klare å skrive til f.eks en fil? Får det bare til å virke når jeg bruker char. Hvis jeg tar utgangspunkt i denne sterkt forenklede koden(har gjort datamedlemmene public for enkelhetsskyld i dette eksemplet):

 

class Data

{

public:

int alder;

char navn[30];

 

}

 

så går det greit å skrive til fil ved å gjøre f.eks slik:

Data data;

strcpy(data.navn, "Frode");

data.alder = 20;

fstream fil("test.dat", ios::in | ios::out | ios::binary);

fstream.write((char *) &data, sizeof(Data));

fstream.close();

 

Dette virker når bruker char, men når jeg prøver med string så blir det problemer(leser/Skriver ikke stringdelen ordentlig). Har prøvd å bruke en fast blokkstørrelse(ikke sizeof), men det hjelper heller ikke.

Noen som vet hva som må gjøres hvis jeg vil bruke string?

Lenke til kommentar

Har ikke tid til forklaring akkurat nå, men her er en liten kodesnutt:

 

#include <fstream>
#include <string>

int main()
{
std::string str;

str = "Frode";

std::ofstream fil("test.txt", std::ios::out);

fil << str;

fil.close();
}

Lenke til kommentar

Hm, er du sikker?

 

#include <fstream>
#include <iomanip>
#include <fstream>
#include <string>

int main()
{
 using namespace std;

 char bin_data[1000];
 ifstream ifil("a.o", ios::in | ios::binary);
 ifil.read(bin_data, 1000);
 ifil.close();

 string str;
 str = "Frode";
 ofstream ofil("test-txt-og-bin.dat", ios::out |  ios::binary);
 ofil << str;
 ofil.write(bin_data, 1000);
 ofil.close();
 
 return(0);
}

Endret av søpple
Lenke til kommentar

Det er nok forholdsvis ulurt å skrive hele objektet i en operasjon, strukturen på objektet er uspesifisert fra kompilatorens side (kan eller kan ikke inneholde RTTI f.eks). Det er for slike operasjoner at man overlaster operator <<.

Lenke til kommentar

frq:

Du kan ikke skrive ut et helt objekt "i en operasjon", om du ikke definerer en egen funksjon for hvert objekt (edit: klasse) som tar seg av dette.

 

Som A_N_K nevner, så er det å overlaste operator<< det beste valget (med tanke på det å definere en funksjon som tar seg av dette).

 

class B {

public:

char* str;

};

 

class A {

public:

char* str;

B* b;

};

 

A a;

 

..hvordan ville det gått å skrive ut a nå tror du? Du ville hatt samme problem om du brukte string fremfor char* her så klart .. det du/vi går over på nå er et helt annet problem/emne enn tidligere, og ikke relatert i det hele tatt med fordeler ved å bruke string fremfor char*.

 

Edit:

http://www.informit.com/articles/article.a...170909&seqNum=1

http://www.codeproject.com/cpp/cfraction.asp

Endret av søpple
Lenke til kommentar
#include <iostream>
#include <fstream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;


class Person {
public:
 int alder;
 string navn;
}; 


ostream& operator<<(ostream& o, Person& data)
{
 o << data.alder << endl;
 o << data.navn << endl;
} 


istream& operator>>(istream& i, Person& data)
{
 i >> data.alder;
 i >> data.navn;
} 


int main()
{
 Person person1;
 person1.alder = 24;
 person1.navn = "Lars";
 ofstream ofil("test.dat", ios::out |  ios::binary);
 ofil << person1;
 ofil.close();

 ifstream ifil("test.dat", ios::in |  ios::binary);
 Person person2;
 ifil >> person2;
 cout << "alder: " << person2.alder << endl;
 cout << "navn: " << person2.navn << endl;
 ifil.close();
 
 return(0);
}

Lenke til kommentar

Her er løsningen på problemet jeg siktet til når jeg sa "..hvordan ville det gått å skrive ut a nå tror du?":

 

#include <iostream>
#include <fstream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;


class Addresse {
public:
 int husnummer;
 string gatenavn;
 string by;
}; 


ostream& operator<<(ostream& o, Addresse& addresse)
{
 o << addresse.husnummer << endl;
 o << addresse.gatenavn << endl;
 o << addresse.by << endl;
 return(o);
} 


istream& operator>>(istream& i, Addresse& addresse)
{
 i >> addresse.husnummer;
 i >> addresse.gatenavn;
 i >> addresse.by;
 return(i);
} 


class Person {
public:
 Person()
   :addresse(new Addresse)
 {
 }

 ~Person()
 {
   delete(addresse);
 }

 int alder;
 string navn;
 Addresse* addresse;
}; 


ostream& operator<<(ostream& o, Person& person)
{
 o << person.alder << endl;
 o << person.navn << endl;
 o << *person.addresse << endl;
 return(o);
} 


istream& operator>>(istream& i, Person& person)
{
 i >> person.alder;
 i >> person.navn;
 i >> *person.addresse;
 return(i);
} 


int main()
{
 Person person1;
 person1.alder = 24;
 person1.navn = "Lars";
 person1.addresse->gatenavn = "Blekebakkvegen";
 person1.addresse->husnummer = 24;
 person1.addresse->by = "Skien";

 ofstream ofil("test.dat", ios::out |  ios::binary);
 ofil << person1;
 ofil.close();

 ifstream ifil("test.dat", ios::in |  ios::binary);
 Person person2;
 ifil >> person2;
 cout << "alder: " << person2.alder << endl;
 cout << "navn: " << person2.navn << endl;
 cout << "gatenavn: " << person2.addresse->gatenavn << endl;
 cout << "husnummer: " << person2.addresse->husnummer << endl;
 cout << "by: " << person2.addresse->by << endl;
 ifil.close();
 
 return(0);
}

 

...magi? ... :]

Endret av søpple
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...