/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Forklar liige dette
Fra : Goo9


Dato : 28-01-02 16:27

Nogen, der lige vil forklare mig hvad de forskellige ting i den følgende
kode gør. Altså hvad den lille bindestreg mellem *streng og 'a' betyder osv.

-Anders;

#include <iostream.h>

void stor(char *streng)
{
while (*streng)
{
if ((*streng >= 'a') && (*streng <= 'z'))
*streng = *streng - 'a' + 'A';

cout << *streng++;
}
}
void main(void)
{
char tekst[] = "Hey monti!";
stor(tekst);
}



 
 
Christian Hemmingsen (28-01-2002)
Kommentar
Fra : Christian Hemmingsen


Dato : 28-01-02 16:36

"Goo9" <Goo9@en.ko> writes:

> Nogen, der lige vil forklare mig hvad de forskellige ting i den følgende
> kode gør. Altså hvad den lille bindestreg mellem *streng og 'a' betyder osv.

Det er såmend et binært minus.

--
Christian Hemmingsen

Claus Rasmussen (28-01-2002)
Kommentar
Fra : Claus Rasmussen


Dato : 28-01-02 16:48

Goo9 wrote:

> Nogen, der lige vil forklare mig hvad de forskellige ting i den følgende
> kode gør. Altså hvad den lille bindestreg mellem *streng og 'a' betyder
> osv.
>
> *streng = *streng - 'a' + 'A';

Det er et trick til at gøre et lille bogstav stort. Det bygger på, at
ASCII tabellen (dvs. dit tegnsæt) har bogstaverne arrangeret således
at alle små bogstaver kommer efter hinanden. Det samme med de store
bogstaver.

F.eks har 'a' tegnkode 97 i ASCII tabellen. Derefter kommer 'b' med
kode 98 osv. Tegnet 'A' har kode 65 og ellers er det det samme som
for de små bogstavers vedkommende.

Tager vi nu et vilkårligt lille bogstav - f.eks 'e', der har kode
101 - og trækker tegnkoden for 'a' (97) får vi e's nummer i bogstav-
rækkefølgen: 4 (nulbaseret). Da vi ved at bogstaverne kommer i
rækkefølge, og da vi ved, at de store bogstaver starter med kode
65, kan vi bruge det til at finde det tilsvarende store bogstav:

'A'+4 = 65+4 = 69 = 'E' .

Hele udregningen ser altså således ud:

*streng = *streng - 'a' + 'A'
= ('e' - 'a') + 'A'
= (101 - 97) + 'A'
= 4 + 'A'
= 4 + 65
= 69
= 'E'

Den sidste sætning i loopet:

cout << *streng++;

....skriver det aktuelle tegn ud, og flytter streng pointeren til
det næste tegn. Når pointeren peger på det sidste tegn i stregen
(der altid er lig med 0) stopper løkken og funktionen returnerer.

-Claus


Byrial Jensen (28-01-2002)
Kommentar
Fra : Byrial Jensen


Dato : 28-01-02 19:09

Goo9 <Goo9@en.ko> skrev:

> if ((*streng >= 'a') && (*streng <= 'z'))
> *streng = *streng - 'a' + 'A';

Det er allerede forklaret hvordan dette (nogle gange) virker.

Men man bør være opmærksom at det er ikke er portabel kode.
C-definitionen kræver ganske vist at det brugte tegnsæt
indeholder alle de engelske bogstaver fra a til z i både de små
og store varianter, men der er ingen krav om hvordan bogstaverne
skal placeres i forhold til hinanden. Speciel behøver et tegnsæt
ikke at placere de små hhv. store bogstaver fortløbende efter
hindanden som konstruktionen her bygger på.

Den portable måde at gøre det på er

if (islower (*streng))
*streng = toupper (*streng);

eller eventuelt blot

*streng = toupper (*streng);

da toupper() returner argumentet uændret hvis det ikke er et
lille bogstav.

NB. Mine kommentarer gælder for C. Jeg ved godt at de 2 citerede
linjer er klippet ud af et C++-program, men jeg formoder at C++
og C er ens på de behandlede punkter. I modsat fald må en C++-
kyndig korrigere mig.

Claus Rasmussen (28-01-2002)
Kommentar
Fra : Claus Rasmussen


Dato : 28-01-02 19:28

Byrial Jensen wrote:

> Det er allerede forklaret hvordan dette (nogle gange) virker.

Præmieeksemplet på hvornår det ikke virker er IBM tegnsættet
EBCDIC . Det bruges SHJV stadig på AS/400 (pænt store maskiner)
og S/390 (temmeligt store maskiner).

-Claus


Christian Hemmingsen (28-01-2002)
Kommentar
Fra : Christian Hemmingsen


Dato : 28-01-02 19:48

Claus Rasmussen <clr@cc-consult.dk> writes:

> Byrial Jensen wrote:
>
> > Det er allerede forklaret hvordan dette (nogle gange) virker.
>
> Præmieeksemplet på hvornår det ikke virker er IBM tegnsættet
> EBCDIC . Det bruges SHJV stadig på AS/400 (pænt store maskiner)
> og S/390 (temmeligt store maskiner).

Men de fleste sidder jo alligevel og koder COBOL når vi snakker
AS/400, så er det overhovedet aktuelt? Nej, pjat. IBM er underlige. De
bruger jo også pakkede decimal tal på deres mainframes (deriblandt
AS/400), så man skal også passe på nå man laver tricks med typecasting
af taltyper.


--
Christian Hemmingsen

Claus Rasmussen (28-01-2002)
Kommentar
Fra : Claus Rasmussen


Dato : 28-01-02 20:04

Christian Hemmingsen wrote:

> Men de fleste sidder jo alligevel og koder COBOL når vi snakker
> AS/400, så er det overhovedet aktuelt? Nej, pjat. IBM er underlige. De
> bruger jo også pakkede decimal tal på deres mainframes (deriblandt
> AS/400), så man skal også passe på nå man laver tricks med typecasting
> af taltyper.

IBM er ikke underlige. IBM har forretningssans, og derfor 1). et princip
om, at være bagudkompatibel [eller rettere: Deres kunder har et prin-
cip om, at deres /leverandør/ er det] og 2). været i branchen så længe,
at de er nødt til at vedligeholde noget gammelt skrammel

EDCDIC og packed decimals var slet ikke så vanvittigt, den gang IBM
fik ideen givet maskinernes arkitektur, og de programmer der skulle
køre på dem. Til sammenligning, så fandes der dengang også maskiner,
hvor en byte ikke var på 8 bits. Og alternativet til COBOL var FORTRAN
eller Algol-68. IBM var ganske mainstream dengang, men det var bare
ikke deres teknologi, der vandt (på det punkt).

Det lidt groteske ved det hele er, at /grunden/ til IBMs kunder ønsker
denne bagudkompatibilitet er, at deres programmører i årevis har benyttet
sig alle mulige beskidte tricks med tegnsæt/typecasting osv., så koden
slet ikke kan køre på en mere moderne maskine. Ris til egen røv, med
andre ord.

Nu er I advaret

-Claus


Per Abrahamsen (28-01-2002)
Kommentar
Fra : Per Abrahamsen


Dato : 28-01-02 21:50

Byrial Jensen <bjensen@nospam.dk> writes:

> C-definitionen kræver ganske vist at det brugte tegnsæt
> indeholder alle de engelske bogstaver fra a til z i både de små
> og store varianter, men der er ingen krav om hvordan bogstaverne
> skal placeres i forhold til hinanden.

Gælder det også C99?

Jeg mener at have læst at der er kommet en del krav om rækkefølge til
tegnsættet, som både ASCII og EBCDIC opfylder. Men jeg har ikke
standarden.

Byrial Jensen (28-01-2002)
Kommentar
Fra : Byrial Jensen


Dato : 28-01-02 23:51

Per Abrahamsen <abraham@dina.kvl.dk> skrev:
> Byrial Jensen <bjensen@nospam.dk> writes:
>
>> C-definitionen kræver ganske vist at det brugte tegnsæt
>> indeholder alle de engelske bogstaver fra a til z i både de små
>> og store varianter, men der er ingen krav om hvordan bogstaverne
>> skal placeres i forhold til hinanden.
>
> Gælder det også C99?

Ja. Det er et krav i C99 at cifrene '0' til '9' har fortløbende
positioner således at man kan omregne fra en encifret talværdi til
det tilsvarende taltegn ved at lægge '0' til værdien, og den anden
vej ved at trække '0' fra. Men der er ikke noget tilsvarende krav
for bogstaver.

> Jeg mener at have læst at der er kommet en del krav om rækkefølge til
> tegnsættet, som både ASCII og EBCDIC opfylder. Men jeg har ikke
> standarden.

Både ASCII og EBCDIC opfylder mig bekendt cifferkravet.

Per Abrahamsen (29-01-2002)
Kommentar
Fra : Per Abrahamsen


Dato : 29-01-02 09:49

Byrial Jensen <bjensen@nospam.dk> writes:

> Per Abrahamsen <abraham@dina.kvl.dk> skrev:
>> Byrial Jensen <bjensen@nospam.dk> writes:
>>
>>> C-definitionen kræver ganske vist at det brugte tegnsæt
>>> indeholder alle de engelske bogstaver fra a til z i både de små
>>> og store varianter, men der er ingen krav om hvordan bogstaverne
>>> skal placeres i forhold til hinanden.
>>
>> Gælder det også C99?
>
> Ja. Det er et krav i C99 at cifrene '0' til '9' har fortløbende
> positioner således at man kan omregne fra en encifret talværdi til
> det tilsvarende taltegn ved at lægge '0' til værdien, og den anden
> vej ved at trække '0' fra. Men der er ikke noget tilsvarende krav
> for bogstaver.

Heller ikke krav som at 'b' > 'a' eller ('A' - 'a') == ('B' - 'b'),
der opfyldes af både ASCII og EBCDIC?


Byrial Jensen (29-01-2002)
Kommentar
Fra : Byrial Jensen


Dato : 29-01-02 21:28

Per Abrahamsen <abraham@dina.kvl.dk> skrev:
>
> Heller ikke krav som at 'b' > 'a' eller ('A' - 'a') == ('B' - 'b'),
> der opfyldes af både ASCII og EBCDIC?

Ingen af delene er krav i C99.

Mogens Hansen (28-01-2002)
Kommentar
Fra : Mogens Hansen


Dato : 28-01-02 19:53


"Goo9" <Goo9@en.ko> wrote in message
news:3c556dae$0$242$edfadb0f@dspool01.news.tele.dk...

Som det er blevet forklaret af andre forsøger funktionen "stor" at skrive
teksten ud kun med store bogstaver.
Det virker bare ikke!
Prøv med teksten "jeg ønsker åbne æbler".
På min maskine bliver det til "JEG øNSKER åBNE æBLER".

Brug i stedet funktionen "toupper" som findes i standard biblioteket.
Ved at anvende "locale" kan man håndtere forskellige landes regler for hvad
der f.eks. er store og små bogstaver..

F.eks.:

#include <locale>

int main(void)
{
using namespace std;

const char* text = "Jeg ønsker åbne æbler";
char buffer[128];
locale danish("DAN"); // platform specific locale specification

char* dest = buffer;
while(*text) {
*dest++ = toupper(*text++, danish);
}
*dest = '\0';
}

eller

#include <locale>

int main(void)
{
using namespace std;

const char* text = "Jeg ønsker åbne æbler";
char buffer[128];
locale::global(locale("DAN"));

char* dest = buffer;
while(*text) {
*dest++ = toupper(*text++);
}
*dest = '\0';
}



Iøvrigt de sædvanlige småting:

>
> #include <iostream.h>

I C++ hedder det
#include <iostream>

>
> void main(void)

main returnerer altid int. Altså:
int main(void)

Hvis du har eksemplet fra en bog, er det måske værd at overveje om det er
til at finde en bedre.

Venlig hilsen

Mogens Hansen



Morten Brix Pedersen (28-01-2002)
Kommentar
Fra : Morten Brix Pedersen


Dato : 28-01-02 20:23

Mogens Hansen wrote:

> "Goo9" <Goo9@en.ko> wrote in message
> news:3c556dae$0$242$edfadb0f@dspool01.news.tele.dk...
> #include <locale>
>
> int main(void)
> {
> using namespace std;
>
> const char* text = "Jeg ønsker åbne æbler";
> char buffer[128];
> locale danish("DAN"); // platform specific locale specification
>
> char* dest = buffer;
> while(*text) {
> *dest++ = toupper(*text++, danish);
> }
> *dest = '\0';
> }


Nu det er C++, så kan jeg bedre lide denne løsning:

#include <string>
#include <algorithm>
#include <cctype>

int main()
{
std::string str = "Hello World";
std::transform(str.begin(), str.end(), str.begin(), std::toupper);
}

- Morten.


Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408925
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste