[C++/BCB] Makkelijker code ASCII naar Int en omgekeerd *

Pagina: 1
Acties:
  • 106 views sinds 30-01-2008
  • Reageer

  • Plaagje
  • Registratie: April 2002
  • Laatst online: 20-05 15:19

Plaagje

<<Fly & Dive>>

Topicstarter
Om te beginnen nee ik bedoel niet ToInt() :)

Het gaat om de volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if ((sLetter >= 0) && (sLetter <= 9)) iUitkomst = sLetter.ToInt();
else if (sLetter == 'A') iUitkomst = 10;
else if (sLetter == 'B') iUitkomst = 11;
else if (sLetter == 'C') iUitkomst = 12;
else if (sLetter == 'D') iUitkomst = 13;
else if (sLetter == 'E') iUitkomst = 14;
else if (sLetter == 'F') iUitkomst = 15;
else if (sLetter == 'G') iUitkomst = 16;
else if (sLetter == 'H') iUitkomst = 17;
else if (sLetter == 'I') iUitkomst = 18;
else if (sLetter == 'J') iUitkomst = 19;
else if (sLetter == 'K') iUitkomst = 20;
else if (sLetter == 'L') iUitkomst = 21;
else if (sLetter == 'M') iUitkomst = 22;
else if (sLetter == 'N') iUitkomst = 23;
else if (sLetter == 'O') iUitkomst = 24;
else if (sLetter == 'P') iUitkomst = 25;
else if (sLetter == 'Q') iUitkomst = 26;
else if (sLetter == 'R') iUitkomst = 27;
else if (sLetter == 'S') iUitkomst = 28;
else if (sLetter == 'T') iUitkomst = 29;
else if (sLetter == 'U') iUitkomst = 30;
else if (sLetter == 'V') iUitkomst = 31;
else if (sLetter == 'W') iUitkomst = 32;
else if (sLetter == 'X') iUitkomst = 33;
else if (sLetter == 'Y') iUitkomst = 34;
else if (sLetter == 'Z') iUitkomst = 35;


sLetter moet een string zijn, en iUitkomst moet een int / float / double enz zijn.

Toen ik ermee begon dacht ik dat ik makkelijk met een kleine functie kon omrekenen omdat het heel logisch is, maar helaas.
Ik had bedacht: A = 65 ASCII en als je dus naar 10 moet, moet er 55 af.

Maar als je er 55 afhaald krijg je ACSII 10 en dat kan je niet naar int zetten.
Ik heb nog gezocht naar iets dat je de ACSII waarde in int kan uitdrukken, maar dat lukt niet (dus A als 65 weergeven)

Zou iemand hier iets weten om het WEL makkelijk te maken?
(PS: ben pas 1ste jaars student :P)

Flying High!


Verwijderd

Ik weet niet welke string je gebruikt, maar als je toch maar een letter gebruikt, kun je char waarde makkelijk omzetten naar een int.

Ik heb zelf ff een progje gekleid die doet wat jij wil.
het is een form met 2 edits en een knopje (allemaak default nammen van BCB)

als je op de knop dubbel klikt, dan kun je zelf een eventhandler maken(ff voor de duidelijkheid ;) )
daar heb ik deze code onder geplaatst:
C:
1
2
3
4
5
6
7
8
9
10
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  AnsiString sLetter = Edit1->Text;
  int iUitkomst;
  if ((sLetter[1] >= '0') && (sLetter[1] <= '9')) iUitkomst = sLetter.ToInt();
  else if ((sLetter[1] >= 'A') && (sLetter[1] <= 'Z'))
    iUitkomst = sLetter[1] - 55;
  else iUitkomst=255;//als het dus geen cijfer of hoofdletter is, dan maar deze waarde
  Edit2->Text=IntToStr(iUitkomst);
}

ik hoop dat dit is wat je wilt ;)

  • schoene
  • Registratie: Maart 2003
  • Laatst online: 21:51
1) sLetter is een string maar je vergelijkt wel met een char. geen idee of dit al dan niet mag.
C++:
1
2
if ((sLetter >= 0) && (sLetter <= 9)) iUitkomst = sLetter.ToInt();
else if (sLetter >= 'A' && sLetter <= 'Z') iUitkomst = sLetter[1] - 'A' + 10;


edit: net iets te laat :p

[ Voor 18% gewijzigd door schoene op 20-04-2004 13:44 ]


  • Plaagje
  • Registratie: April 2002
  • Laatst online: 20-05 15:19

Plaagje

<<Fly & Dive>>

Topicstarter
Bedankt, dat werkt alleen nu het volgende probleem, hij moet het ook weer terug tekenen, dit was eerst deze code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void TfrmMain::ZoekLetter(int iGetal, String &sUitkomst)

if ((iGetal >= 0) && (iGetal <= 9)) sUitkomst = iGetal;
else if (iGetal == 10) sUitkomst = 'A';
else if (iGetal == 11) sUitkomst = 'B';
else if (iGetal == 12) sUitkomst = 'C';
else if (iGetal == 13) sUitkomst = 'D';
else if (iGetal == 14) sUitkomst = 'E';
else if (iGetal == 15) sUitkomst = 'F';
else if (iGetal == 16) sUitkomst = 'G';
else if (iGetal == 17) sUitkomst = 'H';
else if (iGetal == 18) sUitkomst = 'I';
else if (iGetal == 19) sUitkomst = 'J';
else if (iGetal == 20) sUitkomst = 'K';
else if (iGetal == 21) sUitkomst = 'L';
else if (iGetal == 22) sUitkomst = 'M';
else if (iGetal == 23) sUitkomst = 'N';
else if (iGetal == 24) sUitkomst = 'O';
else if (iGetal == 25) sUitkomst = 'P';
else if (iGetal == 26) sUitkomst = 'Q';
else if (iGetal == 27) sUitkomst = 'R';
else if (iGetal == 28) sUitkomst = 'S';
else if (iGetal == 29) sUitkomst = 'T';
else if (iGetal == 30) sUitkomst = 'U';
else if (iGetal == 31) sUitkomst = 'V';
else if (iGetal == 32) sUitkomst = 'W';
else if (iGetal == 33) sUitkomst = 'X';
else if (iGetal == 34) sUitkomst = 'Y';
else if (iGetal == 35) sUitkomst = 'Z';   
}

Toen ik de andere code zag dacht ik dit kan worden:
code:
1
2
3
4
5
6
void TfrmMain::ZoekLetter(int iGetal, String &sUitkomst)
{
  if ((iGetal >= '0') && (iGetal <= '9')) sUitkomst[1] = iGetal;
  else if ((iGetal >= '10') && (iGetal <= '35'))
    sUitkomst[1] = sUitkomst[1] + 55;
}


Dit werkt alleen niet, waarschijnlijk doe ik iets doms fout, maarja wat?

[ Voor 14% gewijzigd door Plaagje op 20-04-2004 14:00 ]

Flying High!


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

In plaats van onleesbare lappen code te posten: omschrijf je probleem eens. Op deze manier ga ik er zelf niet aan beginnen iig.... :/

Professionele website nodig?


  • Plaagje
  • Registratie: April 2002
  • Laatst online: 20-05 15:19

Plaagje

<<Fly & Dive>>

Topicstarter
Oke, zal het proberen:
Het is dus de bedoeling als ik dat als ik 10 invoer er A uitkomt, als ik 12 invoer er C uitkomt t/m 35 bij de invoer en dat er dan Z uitkomt.

De invoer is een Int, en de uitkomst moet een String zijn.

Eerst had ik de, als in de vorige post aangegeven code.

Na een reactie van duck_lucifer bleek dat het eerste gedeelte (zie Startpost)makkelijker kon, maar nu moet het 2e gedeelte nog:

Nadat ik naar zijn code had gekeken dacht ik dat ik wel iets had gevonden, maarja dat werkte dus niet. de code die ik had bedacht was, in dezelfde void:
code:
1
2
3
  if ((iGetal >= '0') && (iGetal <= '9')) sUitkomst[1] = iGetal;
  else if ((iGetal >= '10') && (iGetal <= '35'))
    sUitkomst[1] = sUitkomst[1] + 55;
Hier deed ik dus iets fout mee, maar wat?

Flying High!


Verwijderd

Plaagje schreef op 20 april 2004 @ 14:23:
Oke, zal het proberen:
Het is dus de bedoeling als ik dat als ik 10 invoer er A uitkomt, als ik 12 invoer er C uitkomt t/m 35 bij de invoer en dat er dan Z uitkomt.

De invoer is een Int, en de uitkomst moet een String zijn.
Dat klopt niet met de topic-titel dan...

Maar ga eerst eens nadenken wat het verschil is tussen 0 en '0'... |:(

Weet je het verschil, dan voor kun je voor het eerste character van de string gaan programmeren dat voor 0 <= getal <= 9, je '0' + getal als karakter kunt nemen, en anders 'A' + (getal - 10). Dit is dan het eerste karakter, vergeet daarna niet de string-terminitor ('\0')

En met single quotes kun je maar 1 char initialiseren, dus '10' kan helemaal niet! Dat krijg je hopelijk ook niet door de strot van je compiler geduwd...

[ Voor 35% gewijzigd door Verwijderd op 20-04-2004 16:32 ]


  • Plaagje
  • Registratie: April 2002
  • Laatst online: 20-05 15:19

Plaagje

<<Fly & Dive>>

Topicstarter
Verwijderd schreef op 20 april 2004 @ 14:41:
[...]

Dat klopt niet met de topic-titel dan denk ik...

....

En met single quotes kun je maar 1 char initialiseren, dus '10' kan helemaal niet! Dat krijg je hopelijk ook niet door de strot van je compiler geduwd...
De topic titel kwam overeen met mijn eerste post, maar die was al snel opgelost, het 2e probleem, staat hierboven en is dus int To ACSII.

met die quotes dacht ik ook, maar als ik er geen gebruik geeft het programma een fout als ik de functie uitvoer (maar de compiler niet), als ik ze wel gebruik geeft die geen fout, maar ook geen resultaat.

En 0 t/m 9 vertalen van string naar int is geen probleem, alleen van A een 10 maken van B een 11 maken enz. is een probleem.

Flying High!


  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
Plaagje schreef op 20 april 2004 @ 14:23:
Hier deed ik dus iets fout mee, maar wat?
Je vergelijkt nu iGetal met de ASCII codes van de karakters, weet je zeker dat dat is wat je wilt?

---

Het ziet er overigens uit of je 'nummers' in base X om wilt zetten naar hun waarde in base 10, en andersom. Ik gebruik dan meestal een array met alle nummers/tekens.

getal -> teken wordt dan gewoon array[getal], en teken -> getal is dan gewoon de index in array waar teken staat.
Verwijderd schreef op 20 april 2004 @ 14:41:
Dat klopt niet met de topic-titel dan denk ik...
De titel was het oorspronkelijke probleem, de TS wil nu de inverse uitvoeren.
En met single quotes kun je maar 1 char initialiseren, dus '10' kan helemaal niet! Dat krijg je hopelijk ook niet door de strot van je compiler geduwd...
Daar verbaasde ik me ook al over, maar gcc geeft alleen een warning. En icc geeft zelfs helemaal geen kik. Ik weet echter ook niet precies wat de standaard daar over zegt. Goede stijl lijkt het me in ieder geval niet.

offtopic:
Zie ik nu dat het eerste karakter van een AnsiString s verkregen wordt door s[1] ?!?


--- edit ---
Plaagje schreef op 20 april 2004 @ 14:47:
met die quotes dacht ik ook, maar als ik er geen gebruik geeft het programma een fout als ik de functie uitvoer (maar de compiler niet), als ik ze wel gebruik geeft die geen fout, maar ook geen resultaat.
In regel 3 tel je wel 55 op bij 10 t/m 35 om de ASCII code van die letter te krijgen, maar in regel 1 tel je niet de ASCII code van '0' bij iGetal op om de ASCII code van '0' t/m '9' te krijgen.

[ Voor 19% gewijzigd door _Squatt_ op 20-04-2004 14:53 ]

"He took a duck in the face at two hundred and fifty knots."


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik snap er geen bal van. Wel wat je probleem is, maar niet waarom dat nou een probleem is.

Je hebt aan de ene kant een string, die bestaat uit character-waarden. Aan de andere kant heb je integer waardes. Je wilt dus de chars '0'..'9' omzetten naar 0..9, en 'A'..'Z' omzetten naar 10..35. Correct?

Daarna wil je de 0..9 weer omzetten naar '0'..'9', en 10..35 naar 'A'..'Z'. Ook correct?

Let nu eens op het gebruik van quotes in mijn post, en kijk nog eens een keer naar jouw code. En dan doel ik op dit stukje:
C++:
1
2
3
  if ((iGetal >= '0') && (iGetal <= '9')) sUitkomst[1] = iGetal;
  else if ((iGetal >= '10') && (iGetal <= '35'))
    sUitkomst[1] = sUitkomst[1] + 55;


iGetal is een int, toch vergelijk je 'm met chars. En het moge duidelijk zijn dat '10' en '35' geen geldige chars zijn

[ Voor 26% gewijzigd door .oisyn op 20-04-2004 14:55 ]

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.


Verwijderd

edit:
Laat maar! AnsiString staat tot Ansi-C++ string, zoals "Delphi stdcall" staat tot "C++Builder stdcall" |:(

[ Voor 98% gewijzigd door Verwijderd op 20-04-2004 15:24 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat is well-documented als ik me niet vergis ;)
Volgens mij stamt dat idd af van Pascal waar de eerste byte werd gebruikt om de lengte in op te slaan

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.


  • schoene
  • Registratie: Maart 2003
  • Laatst online: 21:51
Yep, idd. AnsiString offset begint bij 1. verschrikkelijk irritant als je het mij vraagt, maar ja.

En behalve de opmerkingen over quotes

sUitkomst[1] = sUitkomst[1] + 55;

ben je zeker dat je dit wil?

Verwijderd

Nou daar ben ik weer, heb weer ff gekleid :)
ik heb verder gewerkt in de vorige versie zeg maar, er is nu een extra button en edit bijgekomen.


C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  int iGetal = Edit2->Text.ToInt();
  AnsiString  sUitkomst;
  char cWaarde;
  if ((iGetal >= 0) && (iGetal <= 9))
    sUitkomst = IntToStr(iGetal);
  else if((iGetal >= 10) && (iGetal <= 35))
  {
    cWaarde = iGetal+55;//helaas een andere makelijke manier is er niet
    sUitkomst = cWaarde;// de enige ander manier die ik vonde was: sUitkoms.sprintf("%c",iGetal+55) 
                        //maar voor de beginnende programmeur minder makkelijk
  }
  else
    sUitkomst="?";
  Edit3->Text=sUitkomst;
}

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Nou kan ik gek zijn, maar wat is er mis met sUitkomst = ( (i-10) + 'A' ) ? Of zonder if-statement, en universeel:
code:
1
2
char const* const letter = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sUitkomst = letter[ iGetal ];

[ Voor 8% gewijzigd door MSalters op 21-04-2004 10:08 . Reden: constje vergeten ]

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


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

MSalters schreef op 21 april 2004 @ 00:00:
Nou kan ik gek zijn, maar wat is er mis met sUitkomst = ( (i-10) + 'A' ) ? Of zonder if-statement, en universeel:
code:
1
2
char const* letter = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sUitkomst = letter[ iGetal ];
Wat, een uitgeoptimaliseerde lookupbased oplossing voor een simpel probleem? Dat kan toch niet :+

[ Voor 7% gewijzigd door curry684 op 21-04-2004 00:36 ]

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom static? Het is een pointer, geen char array (de string waar ie naar wijst is al vrij statisch ;))

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.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

.oisyn schreef op 21 april 2004 @ 00:22:
Waarom static? Het is een pointer, geen char array (de string waar ie naar wijst is al vrij statisch ;)
:X

Professionele website nodig?


Verwijderd

MSalters schreef op 21 april 2004 @ 00:00:
Of zonder if-statement, en universeel:
C:
1
2
char const* const letter = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sUitkomst = letter[ iGetal ];
...en diezelfde char array kun je dan eveneens gebruiken voor de conversie van ASCII => int, met behulp van een eigen compare-loop

Bijvoorbeeld:
C:
1
2
3
4
5
6
7
8
9
10
11
12
int result = -1;

for (int i = 0; i < 36; i++)
{
    if (sLetter == letter[i])
    {
        result = i;
        break;
    }
}

return result;

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Voor de inverse lookup zijn slimmere dingen te doen. O(n) lookup is nergens voor nodig; O(logN) is ook mogelijk, en met eenmalige O(N) initialisatie maak je een reverse lookup array.

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Die O(log n) is ook simpel te bereiken met je forward lookup array, dus daar is niet eens initialisatie voor nodig :)

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char const* const letter = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int start = 0, end = 36;
while (start != end)
{
    int pos = (start + end) / 2;
    if (sLetter == letter[pos])
        return pos;
    if (sLetter < letter[pos])
        end = pos;
    else
        start = pos + 1;
}

return CHAR_NOT_FOUND;

[ Voor 61% gewijzigd door .oisyn op 22-04-2004 13:23 ]

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: 09-04 22:08
Maar dat werkt niet als 'A' > 'Z' (8> :X

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Lekker boeiend :) Ken jij een platform waarvoor dat geldt?

[ Voor 55% gewijzigd door .oisyn op 22-04-2004 14:38 ]

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.


Verwijderd

MSalters schreef op 22 april 2004 @ 14:09:
Maar dat werkt niet als 'A' > 'Z' (8> :X
Ik zou me dan eerder druk maken over '9' > 'A' :X

Als 'A' > 'Z' zou gelden dan werkt namelijk nagenoeg geen enkele conversie in dit topic 8)7

En als 'A' > 'Z' zou gelden, dan kom je met O(logn) mogelijk op dusdanig veel overhead tegenover max 36+1 mogelijkheden, dat gemiddeld O(n) met lookuptabel waarschijnlijk net zo snel of sneller is (verwacht ik stiekem)...

[ Voor 28% gewijzigd door Verwijderd op 22-04-2004 15:48 . Reden: buffer.insert(" met lookuptabel", pos); ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je zit ook nog met caching. Het is slechts een buffertje van 36 bytes. Als je met mijn methode op '0' zou gaan zoeken dan heb je dus theoretisch kans op 2log 36 = 5 cache misses, wat misschien wel duurder is dan van voor naar achter door de array lopen ;)

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: 09-04 22:08
Hoezo ? Volgens mij heb je hooguit 2 cache lines, 1 als je 32 bytes lines hebt. Alle caches zijn zo opgezet dat twee opeenvolgende lines naar verschillende cache posities mappen, dus je hebt nooit meer dan 2 cache misses, en dat is dus hetzelfde risico als voor linear search.

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dan mag jij eens uitleggen waarom een backward buffer copy velen malen langzamer is dan een forward buffer copy :)

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: 09-04 22:08
Aliasing kansen, de writes zijn slecht voor je cache (8>

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

Pagina: 1