Nieuws:

We zijn er weer.

Na lange tijd van afwezigheid zijn we er weer  :laugh:
We hebben alle wachtwoorden gereset, je oude wachtwoord werkt niet meer.Je moet via het "wachtwoord vergeten"-linkje je wachtwoord resetten. Je krijgt hiervoor een mailtje op het adres dat je bij ons geregistreerd hebt.

De komende tijd zijn we nog druk bezig om de rest van de site op te bouwen, dus het kan zijn dat sommige onderdelen (tijdelijk) niet werken.

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: (C++) Strings opvullen met spaties  (gelezen 5802 keer)

Offline BailHope

  • Lid
    • Techneut
  • Steunpunt: Nee
(C++) Strings opvullen met spaties
« Gepost op: 2009/01/22, 19:49:02 »
Ik heb een oefening voor school die ik maar niet aan de praat krijg.
Deze is uit te werken in C++.

De opdracht is om drie strings, elk met een vaste lengte naar een bestand te schrijven. Daarna moet je die er dan terug uitlezen.
Het probleem ligt hem bij die vaste lengte. De lengte van de Strings moet je zelf opvullen met spaties, zodat je
"<hoop spaties> string" krijgt, moest de String te kort zijn.

De code die de String opvult is de volgende:
string fillString(char* toFill, int maxSize)
{
    int numberOfSpaces = maxSize - strlen(toFill);
    char result[maxSize];

    for (int i = 0; i < numberOfSpaces; i++)
    {
        result[i] = ' ';
    }

    for (int i = 0; i < maxSize-numberOfSpaces; i++)
    {
        result[numberOfSpaces + i] = toFill[i];
    }

    return result;
}

Volgens mij werkt deze methode correct. De eerste string van 9 karakters wordt correct opgevuld met 11 spaties en weggeschreven naar het bestand.
De tweede String komt eigenlijk binnen als een Integer, dus ik zet die om naar een String met de volgende code:
   char hoogte[4];
    sprintf(hoogte, "%d", boom.getHoogte());
Als ik dan de inhoud van hoogte afdruk naar cout, krijg ik de correcte hoogte, dus ik neem aan dat de omzetting ook werkt.
Als ik dan deze hoogte doorgeef naar fillString (hierboven), gaat er klaarblijkelijk toch iets fout, want dit is de output:
šìø·­Ïë·Ó‹ ø

Een hele hoop onzinnige tekens, dus. Ik dacht al dat ik misschien de pointer-referentie aan het afdrukken ben, in plaats van de eigenlijke waarde. In dat geval begrijp ik niet wat ik verkeerd doe.
Ik geef deze waarde zo door:
output += fillString(omvang, 4);Hierbij is omvang gelijk aan een String van 2 of 3 characters, en is '4' de grootte van de String die ik wil terugkrijgen.

Kunnen jullie hier aan uit?
Ubuntu user #12046
Mijn blog voor techneuten: http://techneut.wordpress.com
Voor de professionele IT'er: http://it-potato.blogspot.com

Offline Double12

  • Webteam
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #1 Gepost op: 2009/01/22, 20:42:02 »
Ik heb geen heel goed inzicht wat je allemaal hebt geprogrammeerd, maar één ding valt me wel op.
De functie fillString heeft als returnwaarde een string (een C++ string), maar je geeft uiteindelijk de variabele result terug: een char[] (array van characters).

Sowieso is het misschien handiger om in het programma meer met C++ strings te werken en minder met char* (C-string). Behalve als dat de opdracht van school is natuurlijk.

Offline BailHope

  • Lid
    • Techneut
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #2 Gepost op: 2009/01/22, 21:14:01 »
Ik heb geen heel goed inzicht wat je allemaal hebt geprogrammeerd, maar één ding valt me wel op.
De functie fillString heeft als returnwaarde een string (een C++ string), maar je geeft uiteindelijk de variabele result terug: een char[] (array van characters).

Sowieso is het misschien handiger om in het programma meer met C++ strings te werken en minder met char* (C-string). Behalve als dat de opdracht van school is natuurlijk.

Je geeft goede raad maar daar ligt het probleem volgens mij niet. In C++ wordt een array van characters gelijkgesteld aan een String.
Je kan uiteindelijk ook:
char woord[5] = {'a','b','c','d','e'};
string tweedeWoord = woord
doen.

Ik krijg dus drie waarden binnen. Dat is één String, en twee Integers.
De bedoeling is dat deze naar een bestand geschreven worden. Maar ze moeten eerst allemaal omgevormd worden tot een vaste lengte. Als ze te kort zijn, moeten ze dus opgevuld worden met spaties tot ze aan de gewenste lengte komen.
Die String omvormen is makkelijk genoeg en verloopt probleemloos.

Als ik de Integers wil omvormen, gooi ik ze via de functie 'sprintf' in een array van characters van 4 bytes.
Dan geef ik ze ook aan mijn fillString functie. De integers moeten tot 4 characters opgevuld worden (ze zijn oftewel 2 oftewel 3 characters groot). Maar daar loopt het dus fout. De omvorming heb ik al gecontroleerd. Deze verloopt juist.
In totaal wordt per lijn (Een String en twee Integers) drie keer de fillString methode aangeroepen.
Telkens wordt het resultaat van de methode fillString toegevoegd aan een al bestaande String, met de volgende code:
"output += fillString(omvang, 4);"
Zodra output een volledige lijn bevat, schrijf ik die weg naar het bestand.

Mijn vermoeden is dus dat er iets foutloopt in die lijn waar ik aan 'output' concateneer, maar ik zou niet weten wat.
Ubuntu user #12046
Mijn blog voor techneuten: http://techneut.wordpress.com
Voor de professionele IT'er: http://it-potato.blogspot.com

Offline profoX

  • Lid
    • wesley
    • Lionslink
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #3 Gepost op: 2009/01/22, 22:09:11 »
de makkelijke manier zou allesinds zijn:

#include <iostream>

#define MAX_LEN 10

using namespace std;

int main(void) {
    char a[MAX_LEN + 1], b[MAX_LEN + 1], c[MAX_LEN + 1];
    sprintf(a, "%*d", MAX_LEN, 12345);
    sprintf(b, "%*s", MAX_LEN, "blaablabla");
    sprintf(c, "%*s", MAX_LEN, "foobar");
    cout << a << endl << b << endl << c << endl;
    return 0;
}

wesley@hox:~/dev$ ./testcpp
     12345
blaablabla
    foobar

maar wel opletten met sprintf() want die format width specifier daar voorkomt geen buffer overflow..!
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline profoX

  • Lid
    • wesley
    • Lionslink
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #4 Gepost op: 2009/01/22, 22:23:58 »
De eigenlijke fout is echter dat dit:
for (int i = 0; i < maxSize-numberOfSpaces; i++)
moet worden vervangen door:
for (int i = 0; i <= maxSize-numberOfSpaces; i++)
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline BailHope

  • Lid
    • Techneut
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #5 Gepost op: 2009/01/22, 22:43:51 »
De eigenlijke fout is echter dat dit:
for (int i = 0; i < maxSize-numberOfSpaces; i++)
moet worden vervangen door:
for (int i = 0; i <= maxSize-numberOfSpaces; i++)

Dat klopt!  Plotseling wordt mijn output wel zinnig.

Hoe kan dat? Op zo iets had ik niet gelet, want als nu het laatste teken niet wordt overgezet, wat maakt dat nu uit? Blijkbaar maakt het veel uit, natuurlijk, maar ik begrijp niet echt waarom :s
Ik zou verwachten dat ik dan maar 3 van de 4 tekens zou krijgen of zo ...
Ubuntu user #12046
Mijn blog voor techneuten: http://techneut.wordpress.com
Voor de professionele IT'er: http://it-potato.blogspot.com

Offline profoX

  • Lid
    • wesley
    • Lionslink
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #6 Gepost op: 2009/01/23, 09:26:51 »
Het laatste teken is '\0', indien dat er niet bijzit kan C/C++ bv. niet controleren hoe lang een string is d.m.v. strlen(),
want strlen() (en het afdrukken van strings of char arrays) heeft die '\0' nodig om te weten waar de string eindigt.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

Offline SeySayux

  • Lid
    • SeySayux.net
  • Steunpunt: Nee
Re: (C++) Strings opvullen met spaties
« Reactie #7 Gepost op: 2009/01/23, 16:17:20 »
#include <iostream>
#include <string>

inline string operator * (string str, std::size_t times) {
      string s = "";
      for(std::size_t i = 0; i < times; i++) s.append(str);
      return s;
}

inline string fill_space(string & str, std::size_t full_length) {
    std::size_t len = str.length();
    return len > full_length ? str : string(" ")*(full_length-len)+str;
}

#define STRING_LENGTH 10
#define pr(x) std::cout << x << endl

int main() {
    string s1 = "foobar"
    string s2 = "abc"
    string s3 = "helloworld";
    pr(s1);
    pr(s2);
    pr(s3);
    return 0;
}

Dit is hoe ik het zou doen. Geen garantie!

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net