Gå til innhold

string, char, stream & vector


Anbefalte innlegg

Er det noen som ser hva som er feil her:

 

if ( !in.get( ch, MAXCHAR+1, TERMINATOR ) ){break;}
shape.push_back( ch );

 

lagret i shape blir bare søppel, og når jeg går ut av metoden er det ingenting!

Hiver jeg inn en adresse kanskje?

Hvordan skal dette egentlig gjøres?

 

(leser fra en fil, og henter strengen inn i en tabell av type: vector<string> shape; )

Lenke til kommentar
Videoannonse
Annonse

Koden du viser ser grei nok ut den. Men hva er ch? Sannsynligvis ligger feilen din der. I ditt eksempel bør ch være:

char ch[MAXCHAR+1];

 

Hvis shape vektoren din ikke "husker" verdiene sine tyder på at du har den som inn-argument og "by value".

 

Dvs. slik:

void MyMethod(std::vector<std::string> vec)
{
   // gjøre noe med vec..
   // endringer vil bli borte når funksjon går "out of scope"
}


// mens det kanskje det er noe sånt du er ute etter:

void MyMethodWithRef(std::vector<std::string> & vec)
{
   // endringer i vec vil bli husket siden vec er en referanse
}

Lenke til kommentar

A_N_K:

Helt enig, men problemet er at ch er definert slik kjetil sier allerede, og at shape er en medlemsvariablel som metoden arbeider direkte på... Når jeg så bruker den i en annen metode (ved et senere kall selvsagt) får jeg fortsatt feil verdi.

 

Tro meg, jeg slet med dette problemet noen timer før jeg postet her(og jeg har et par tykke bøker liggende ved min side når jeg programerer).

Lenke til kommentar

Du har ikke funnet en løsning ennå?

 

Kunne du pastet hele koden, eventuellt isolert problemet/koden (gjerne i et fungerende program, med main() og stuff (jeg er lat))? Utrolig tungvinnt når man ikke ser typer og sammenhengen o.s.v.

 

Om mulig, paste gjerne filen du leser fra også.

 

For mye er bedre enn for lite.

Endret av søppel
Lenke til kommentar

Begynnte akkurat på det igjen og sjekket om jeg hadde fått noen svar her først.

Selvsagt kan jeg poste koden... Ikke noen hemmeligheter her:

 

/*=============================================================================
Function:       readShapeDefenitions( )
Description:    Reads the shape defenitions to use from file into the shape &
   shape color arrays.
Parameters:     - void - 
Returns:        - void -
=============================================================================*/
void Tetris::readShapeDefenitions( )
{
// constants
const int MAXCHAR = 16;      // only need to read 16 chars
const char TERMINATOR = ';';    // the terminator

// variables
ifstream in( SHAPES_FILENAME );    // the stream w/ defenitions
char ch[MAXCHAR+1];      	// holds a string read
char c1;        	// holds a char read
color clr;        	// the color read

string test;

// read character by character from stream & store shape defenitions for
// use in the program:
while( !in.eof() )
{
 // comment -> ignore rest of line
 if ( in.peek() == '#' )	
 {
 	while( in.get(c1) )
   if(c1 == '\n'){break;}	// break from loop when eol
 }
 else if( in.peek( ) == '\n' ){in.ignore(1, '\n');} // ignore eol
 else if( in.peek( ) == ' ' ){in.ignore(1, '\n');} // ignore whitespace
 else
 {
 	// read bitset
 	if ( !in.get( ch, MAXCHAR+1, TERMINATOR ) ){break;}

 	shape.push_back( ch );

 	int a = shape[0].length( );
 	test = shape[0];
 	in.get( );      	// remove delimiter


 	// read colors
 	in.get(ch, MAXCHAR + 1, TERMINATOR);	// red
 	clr.R = atoi(ch);
 	in.get( );

 	in.get(ch, MAXCHAR + 1, TERMINATOR);	// green
 	clr.G = atoi(ch);
 	in.get( );
 	
 	in.get(ch, MAXCHAR + 1, TERMINATOR);	// blue
 	clr.B = atoi(ch);
 	in.get( );

 	shapeColor.push_back(clr);
 }
}

// close stream
in.close( );
}

 

Som du ser har jeg lagt inn noen tester, så det er ikke det at verdien forsvinner heller tror jeg (selv om den ikke har denne verdien i metoden som mottar).

 

a blir 16, men test blir: 0x0012fbcc "x?ÌÌÌÌÌÌÌÌÌÌÌÌ"

ch blir verdien jeg ønsker...

Lenke til kommentar

ok:

 

ch: 0x0012fc18 "0000100010001100" char [17]

ch: 0x0012fc18 "0000000001001110" char [17]

 

- leser kun to linjer foreløpig...

 

Har forresten funnet ut at problemet oppstår når ch er 16 characters(om jeg fjerner en ser det ut til å være i orden), men må tenke litt på det for å se hvorfor, og jeg trenger faktsisk 16...

Lenke til kommentar

Vel, ut i fra koden du har postet er det vanskelig å se hvorfor du skulle få det resultatet du gjør. Char-bufferen din ser ut til å være i orden, men det skjer altså noe galt når du lagrer i en vektor av strenger. Hva med å konstruere en streng direkte fra bufferen, og skrive ut denne?

Lenke til kommentar

Nå er jeg fryktelig bakfull (ennå), men:

 

 if ( !in.get( ch, MAXCHAR+1, TERMINATOR ) ){break;}
 shape.push_back( ch );

 

ch er en "c streng" (char*) .. den må inneholde \0 for å angi slutten på strengen.

 

Det er altså ikke tilfeldig at..

get(char *buffer, streamsize num, char delim);

..leser num - 1 tegn.

Endret av søppel
Lenke til kommentar

eh

Altså, jeg mener, hva er galt her liksom:

string test;
string test2;

test = "abcdefghijklmno";
test2 = "abcdefghijklmnop";

 

..er jo ikke noe kode .. holdt jeg på å si.

 

Edit:

Fikk du forresten med deg posten min ovenfor - den som snakket om c-strenger og \0 ..?

Endret av søppel
Lenke til kommentar

:) det er kode som viser at når jeg har 15 tegn i strengen min, så er alt flott og fint, men straks jeg tar tegn nummer 16 inn i strengen blir det krøll.

 

Leste det du skrev om nullterminerte strenger, men den skal jo ta med nulltermineringen slik jeg har skrevet det, eller ?

 

 

PS: Er forresten på kanten til å kapitulere og gå over til char* istedet...

Endret av Herr_Dude
Lenke til kommentar

Koden sier meg absolutt ingenting ..

 

Så ikke at du hadde deklarert den slik: char ch[MAXCHAR+1]; .. da blir det riktig (altså det er plass til \0'en som den legger til selv) alikevell. Selv om det blir en rar måte å gjøre det på.

 

Skjønner fortsatt ikke hva problemet egentlig er. Her har jeg gjordt selv det jeg bad deg om å gjøre; isolere problemet og plassere det i en main() funksjon (komplett program):

 

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>

using namespace std;


int main(int argc, char *argv[]) {

// constants
const int MAXCHAR = 16;      // only need to read 16 chars
const char TERMINATOR = ';';    // the terminator
#define SHAPES_FILENAME "test.txt"

// variables
//ifstream in( SHAPES_FILENAME );    // the stream w/ defenitions
string file_contents = "0000100010001100\n"
 "0000000001001110\n";

stringstream in(file_contents);
char ch[MAXCHAR + 1];       // holds a string read
char c1;         // holds a char read
//color clr;         // the color read

string test;
vector<string> shape;

// read character by character from stream & store shape defenitions for
// use in the program:
while ( !in.eof() ) {
 // comment -> ignore rest of line
 if ( in.peek() == '#' ) {
 	while ( in.get(c1) )
   if (c1 == '\n') {break;} // break from loop when eol
 } else
 	if ( in.peek( ) == '\n' ) {in.ignore(1, '\n');} // ignore eol
 	else
   if ( in.peek( ) == ' ' ) {in.ignore(1, '\n');} // ignore whitespace
   else {
   	// read bitset
   	if ( !in.get( ch, MAXCHAR + 1, TERMINATOR ) ) {break;}

   	shape.push_back( ch );

   	int a = shape[0].length( );
   	test = shape[0];
   	in.get( );       // remove delimiter

   	cout << shape.back() << endl;

   	/*
   	// read colors
   	in.get(ch, MAXCHAR + 1, TERMINATOR); // red
   	clr.R = atoi(ch);
   	in.get( );

   	in.get(ch, MAXCHAR + 1, TERMINATOR); // green
   	clr.G = atoi(ch);
   	in.get( );

   	in.get(ch, MAXCHAR + 1, TERMINATOR); // blue
   	clr.B = atoi(ch);
   	in.get( );

   	shapeColor.push_back(clr);
   	*/
   }


 // close stream
 //in.close( );
}
}

 

under kjøring:

 

0000100010001100

0000000001001110

 

Hvis du kunne definert hva input er (file_contents), og hva ønsket resultat er; hadde det blitt lett/mulig å finne ut av.

Lenke til kommentar

Men altså, du får skrevet ut char-bufferen fint, som tyder på at den er nullterminert. Har du prøvd å initialisere en streng direkte med bufferen og skrive ut denne? Mistenker at noe går galt i vektoren din. Du har ikke noe i vektoren fra før vel, f.eks opprettet den med en viss størrelse?

Lenke til kommentar

Jeg har funnet feilen... Helt utrolig tåpelig, men jeg skylder dere vel en forklaring / løsning på feilen.

 

Problemet lå et helt annet sted, og jeg vet ikke helt hvordan jeg skal fikse den delen enda, men her er ihvertfall det som kastet meg av sporet:

 

1) Metoden readshapedefinitions kalles opp i konstruktøren, og av en eller annen grunn overlever ikke det jeg leser inn til jeg kaller den fra en annen klasse senere. Dette har jeg ikke helt funnet ut ihvertfall, men jeg gjorde en test på å kalle den opp fra et annet sted, og det funker, men de tingene der skal jeg klare å finne ut av selv.

 

2) Det som virkelig kastet meg av sporet, som jeg ikke skjønte før jeg leste koden til søppel (mange takk forresten) er jeg bruker visual studio. Der kan jeg overvåke variablene så når jeg leste inn så jeg at jeg bare fikk tull (men ikke dersom det var færre en 16). Det viste seg at når jeg skrev verdiene ut til skjermen istedet så fikk jeg de rette verdien. Altså takler ikke Visual studio sin overvåking av verdiene at type string mer enn 15 tegn!

 

Så jeg trodde hele tiden problemet lå der, men det viste seg at grunnen til at de ikke overlevde var at jeg kalte opp metoden fra "feil" sted...

 

Grusomt teit feil egentlig, og jeg skjønte ikke at det var et problem...

 

Tusen takk for hjelpen ihvertfall!

Nå kan jeg endelig komme meg videre...

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...