[C/C++] Newline char verwijderen uit chararray

Pagina: 1
Acties:

  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 26-12-2025
Hallo mensen,

Ik ben weer eens aan de slag gegaan met C++ en zit nu een simpele tile engine die ik in basic had geschreven te maken in C++. Ik gebruik hierbij Dev-C++ (4.9.9.2). Mijn probleem is dat ik in een bestand de namen van de te laden bmp-bestanden heb staan en deze probeer uit te lezen met mijn progje. Het leest namelijk alle tekens inclusief het newline teken. Deze wil ik uit de chararray waar de namen in staan, verwijderen want anders leest het de verkeerde namen in.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
FILE *fTile;

char tileName[20][30];
     
     for (int i = 0; i < mTiles; i++)
     {
         fgets(&tileName[i][0], 50, fTile);

         print(&tileName[i][0], 0, i*8);
         loadBMP(&tileName[i][0], image[i][0], 20, 20);
     }
     
     fclose(fTile);


tileName is hierbij een array waarbij de 20 = aantal te laden tiles, 30 = bestandsnaam. mTiles is het aantal tiles dat er gelezen moeten worden (lees ik uit een ander bestand). Inhoud van het tekstbestand waar de paden naar de tiles staan:

code:
1
2
3
4
5
6
7
8
images/grass.bmp
images/bush.bmp
images/desert.bmp
images/rocks.bmp
images/stone.bmp
images/trees.bmp
images/walls.bmp
images/water.bmp


Ik krijg dus als uitvoer:

code:
1
2
3
4
5
6
7
8
images/grass.bmpX <- X is dan een raar teken
images/bush.bmpX
images/desert.bmpX
images/rocks.bmpX
images/stone.bmpX
images/trees.bmpX
images/walls.bmpX
images/water.bmp


Zoals jullie zien is er geen teken achter water.bmp en die tile laad ie dan ook gewoon goed.

Ik ben nu al 3 dagen bezig om dat ene tekentje te verwijderen, maar mijn hersenen zeggen op het moment: "HO MAAR!!!" Als iemand me in de goede richting zou kunnen schoppen, dan zou ik een gelukkig iemand zijn ;) Alvast bedankt!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-01 23:51

NMe

Quia Ego Sic Dico.

Kun je niet simpelweg '\n' vervangen door '\0' in een loopje?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

Dat is geen c++, dat is standaard c
Bij c++ gebruik je filestreams, en heb je ook geen pointers nodig.

God, root, what is difference? | Talga Vassternich | IBM zuigt


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 26-12-2025
-NMe- schreef op zaterdag 06 mei 2006 @ 22:05:
Kun je niet simpelweg '\n' vervangen door '\0' in een loopje?
Ja weet je wat het is, ik ben nu al 3 dagen (bijna) nonstop bezig met dit kleine maar oh zo irritante probleem en ik kan nu even niet fatsoenlijk meer denken. Wat ik zelf heb kunnen bedenken is dat ik de lengte van de arrays moet zien uit te vogelen en dan bij alle regels behalve de laatste het '\n' teken verwijderen, maar ik heb al op duizend-en-één manieren zo'n loopje gemaakt. Het werkt alleen niet :P
Hoe kan ik de lengte van een array achterhalen?
moto-moi schreef op zaterdag 06 mei 2006 @ 22:07:
Dat is geen c++, dat is standaard c
Bij c++ gebruik je filestreams, en heb je ook geen pointers nodig.
Joa ok, ik ben nog niet zo heel erg thuis in c(++) dus ik haal alles door de war ;)

[Ik hoop niet dat ik overkom als: "doe dit en dat voor me!", maar ik ben een beetje op op het moment

[ Voor 31% gewijzigd door Oguz286 op 06-05-2006 22:13 ]


Verwijderd

strlen loopt door je array tot-ie \0 tegenkomt en geeft dus de lengte van een char array inclusief \n en \r. Als al je tiles op .bmp eindigen kun je daarop zoeken, anders:

C:
1
2
3
4
5
6
7
8
9
char *test = "bestand.bmp\r\n";
unsigned short index = 0;

while ( ( test[ index ] >= 'a' && test[ index ] <= 'z' ) ||
        ( test[ index ] >= 'A' && test[ index ] <= 'Z' ) ||
        ( test[ index ] >= '0' && test[ index ] <= '9' ) ||
          test[ index ] == '.'  ||
          test[ index ] == '/' )
       index++;


index is aantal alfanumerieke tekens en punten in je array

sneller is alleen te zoeken op \r\n in windows, \n in linux en \r op de mac:

C:
1
2
while ( test[ index ] != '\r' && test[ index + 1 ] != '\n' )
      index++;

[ Voor 53% gewijzigd door Verwijderd op 06-05-2006 22:35 ]


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 26-12-2025
Verwijderd schreef op zaterdag 06 mei 2006 @ 22:28:
strlen loopt door je array tot-ie \0 tegenkomt en geeft dus de lengte van een char array inclusief \n en \r. Als al je tiles op .bmp eindigen kun je daarop zoeken, anders:

C:
1
2
3
4
5
6
7
8
char *test = "bestand.bmp\r\n";
unsigned short index = 0;

while ( ( test[ index ] >= 'a' && test[ index ] <= 'z' ) ||
          ( test[ index ] >= 'A' && test[ index ] <= 'Z' ) ||
          ( test[ index ] >= '0' && test[ index ] <= '9' ) ||
          ( test[ index ] == '.' )
         index++;


index is aantal alfanumerieke tekens en punten in je array
Ah kijk aan! Ik ga even kijken of ik er wat mee kan, danku!

Het werkt!

C:
1
2
3
4
5
6
7
8
9
10
11
char tileName[20][30];
     int a;
     
     for (int i = 0; i < mTiles; i++)
    {
         fgets(&tileName[i][0], 50, fTile);
         a = strlen(&tileName[i][0]);
         tileName[i][a - 1] = '\0';
         print(&tileName[i][0], 0, i*8);
         loadBMP(&tileName[i][0], image[i][0], 20, 20);
     }


Waarschijnlijk heel erg quick&dirty, maar hey... het werkt wel! Heel erg bedankt! Ik zal nog wel proberen te optimizen, maar dat doe ik wel wanneer ik even een tijdje niet meer achter mijn pc heb gezeten ;)

[ Voor 34% gewijzigd door Oguz286 op 06-05-2006 22:45 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
Hmm. std::remove lijkt me meer voor de hand te liggen. Had je ook kunnen gokken :)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Xorgye
  • Registratie: Maart 2005
  • Laatst online: 05-10-2024
Oguz286, r is een hele makkelijke functie

fscanf

Doet hetzelfde als fprintf maar leest dan de data uit in het formaat dat jij wilt

Voorbeeld algemeen: fscanf(reeks, "%s %* %i %*\n", naam, leeftijd)
als je dan als reeks neemt 'mama is 50 jaar\n', krijg je in naam 'mama' en in leeftijd '50'.
Een %* slaat hij over, en \n betekend dat ie daar \n moet verwachten (en niet lezen)

In jouw voorbeeld word t dus fscanf(fTile, "%s\n", tileName[i]);

  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 26-12-2025
MSalters schreef op zondag 07 mei 2006 @ 14:31:
Hmm. std::remove lijkt me meer voor de hand te liggen. Had je ook kunnen gokken :)
Ik kwam er gisteren achter dat ik de hele tijd in C zat te proggen ipv C++ :P Dus eigenlijk niet ;)
Xorgye schreef op zondag 07 mei 2006 @ 15:55:
Oguz286, r is een hele makkelijke functie

fscanf

Doet hetzelfde als fprintf maar leest dan de data uit in het formaat dat jij wilt

Voorbeeld algemeen: fscanf(reeks, "%s %* %i %*\n", naam, leeftijd)
als je dan als reeks neemt 'mama is 50 jaar\n', krijg je in naam 'mama' en in leeftijd '50'.
Een %* slaat hij over, en \n betekend dat ie daar \n moet verwachten (en niet lezen)

In jouw voorbeeld word t dus fscanf(fTile, "%s\n", tileName[i]);
Hmm, dat is een stuk netter dan mijn 'oplossing'. Ik zal eensch even kijken, ik heb net koffie gehad ;)
Nu ik toch bezig ben even kijken of ik dit goed heb:

fgetc en fputc gebruik je bij bestanden in binair formaat om telkens 1 byte te lezen / schrijven.
fgets en fputs is voor gebruik bij textbestanden.
fread en fwrite kunnen van alles lezen en schrijven waarbij je het aantal te lezen byten kan instellen.

en dan heb je dus ook nog fscanf en fprintf, die moet ik toch even uitvogelen. Heel erg bedankt!

[ Voor 21% gewijzigd door Oguz286 op 07-05-2006 18:33 ]


  • writser
  • Registratie: Mei 2000
  • Laatst online: 19-02 10:39
In c++ zou ik zoiets gebruiken:

code:
1
2
3
4
5
6
7
8
vector<string> tiles;
string temp;
ifstream file ("data.txt");
while (file.good()) {
  file >> temp;
  tiles.push_back(temp);
}
file.close();

Onvoorstelbaar!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Daar heb je in C++ veel mooiere constructies voor :)
C++:
1
2
3
vector<string> tiles;
ifstream file ("data.txt");
copy(istream_iterator<string>(file), istream_iterator<string>(), back_inserter(tiles));

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
Klein verschil is dat die twee C++ oplossingen woorden kopieren en geen regels.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • igmar
  • Registratie: April 2000
  • Laatst online: 31-01 23:50

igmar

ISO20022

C:
1
2
3
4
5
6
7
char a[] = "Dit is een bmp\r\n";
char *t;

t = strstr(a, "\r\n");
*t = '\0';

printf("%s", a);


doet precies dat :)

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
MSalters schreef op maandag 08 mei 2006 @ 22:16:
Klein verschil is dat die twee C++ oplossingen woorden kopieren en geen regels.
Door file >> temp; te vervangen door getline(file, temp) is dat ook opgelost.
Pagina: 1