/ 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
printf spg
Fra : Kåre Rasmussen


Dato : 23-12-03 17:55

Jeg har lige kastet mig over programmering i C++ og har kigge lidt på nogle
tutorials. Nu er jeg flere gange faldet over %c, %d, %u o.lign.

Hvor kan jeg finde en forklaring på disse "værdier"

Er printf en C eller C++ funktion?

Og så lige det sidste:
Som jeg ser det, skal man i C angive #include med .h (ex #include
<stdio.h>), mens C++ accepterer #include <string>

Er der et sted, hvor dette er beskrevet?

Mvh.
Kåre Rasmussen

 
 
Bertel Brander (23-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 23-12-03 18:13

Kåre Rasmussen wrote:
> Jeg har lige kastet mig over programmering i C++ og har kigge lidt på nogle
> tutorials. Nu er jeg flere gange faldet over %c, %d, %u o.lign.
>
> Hvor kan jeg finde en forklaring på disse "værdier"

Formatet til printf er f.ex. beskrevet her:
http://www.hmug.org/man/3/printf.html

>
> Er printf en C eller C++ funktion?

printf er en C funktion, men kan også bruges i C++
De fleste C++ programører bruger til tider sprintf varianten.

C++ har streams, f.ex:
std::cout << "Hello World" << std::endl;

>
> Og så lige det sidste:
> Som jeg ser det, skal man i C angive #include med .h (ex #include
> <stdio.h>), mens C++ accepterer #include <string>
>

C++ headerfiler findes i to udgaver, en med .h og en uden, du bør
benytte dem uden.
C bruger altid med .h, C headerfilerne har en variant med c foran,
f.ex. cstdio.h, der bør bruges hvis de inkluderes i C++ kode.

/b


Bertel Brander (23-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 23-12-03 18:22

Bertel Brander wrote:

> Kåre Rasmussen wrote:
>
>> Jeg har lige kastet mig over programmering i C++ og har kigge lidt på
>> nogle tutorials. Nu er jeg flere gange faldet over %c, %d, %u o.lign.
>>
>> Hvor kan jeg finde en forklaring på disse "værdier"
>
>
> Formatet til printf er f.ex. beskrevet her:
> http://www.hmug.org/man/3/printf.html
>
>>
>> Er printf en C eller C++ funktion?
>
>
> printf er en C funktion, men kan også bruges i C++
> De fleste C++ programører bruger til tider sprintf varianten.
>
> C++ har streams, f.ex:
> std::cout << "Hello World" << std::endl;
>
>>
>> Og så lige det sidste:
>> Som jeg ser det, skal man i C angive #include med .h (ex #include
>> <stdio.h>), mens C++ accepterer #include <string>
>>
>
> C++ headerfiler findes i to udgaver, en med .h og en uden, du bør
> benytte dem uden.
> C bruger altid med .h, C headerfilerne har en variant med c foran,
> f.ex. cstdio.h, der bør bruges hvis de inkluderes i C++ kode.

Så vidt jeg ved er forskellen på de to typer at den ene type (dem uden
..h og dem med c foran) pakker funktioner mv. ind i namespace std.

/b


Mogens Hansen (24-12-2003)
Kommentar
Fra : Mogens Hansen


Dato : 24-12-03 09:25


"Bertel Brander" <bertel@post4.tele.dk> wrote:

[8<8<8<]
> C++ headerfiler findes i to udgaver, en med .h og en uden, du bør
> benytte dem uden.

Nej.
C++ headere findes ikke i to udgaver.
F.eks. finder der ikke i C++ Standard Library
#include <vector.h>
#include <iostream.h>
selvom sådanne header-filer kan findes i andre biblioteker.

> C bruger altid med .h, C headerfilerne har en variant med c foran,
> f.ex. cstdio.h, der bør bruges hvis de inkluderes i C++ kode.

Nej, ikke
#include <cstdio.h>
De biblioteker som C++ har medtaget fra C includeres med et 'c' foran og
uden noget '.h'.
Altså
#include <cstdio>
Alle funktionerne ligger i namespace "std".

C bibliotekerne kan af kompatibilitetsgrunde includeres på formen
#include <stdio.h>
Dette svarer fuldstændigt til
#include <cstdio>
using std::printf
og tilsvarende "using std::???" for samtlige funktioner i den pågældende
header. (Se §D.5 i C++ Standarden)
Denne form er dog deprecated (se §C2.1 i C++ Standarden).


Glædelig Jul.

Venlig hilsen

Mogens Hansen



Igor V. Rafienko (24-12-2003)
Kommentar
Fra : Igor V. Rafienko


Dato : 24-12-03 00:53

[ Kåre Rasmussen ]

[ ... ]

> Hvor kan jeg finde en forklaring på disse "værdier"


<URL: http://www.dinkumware.com/>

[ ... ]


> Som jeg ser det, skal man i C angive #include med .h (ex #include
> <stdio.h>), mens C++ accepterer #include <string>
>
> Er der et sted, hvor dette er beskrevet?


Nøyaktig hva vil du ha beskrevet her? Navnekonvensjoner for
headerfiler? Standardene for begge språkene lister opp hvilke
headerfiler skal finnes i standardbiblioteket. C++-standarden
inneholder også litt informasjon om kompatibilitet mot C sine headere.





ivr
--
<html><form><input type crash></form></html>

Mogens Hansen (24-12-2003)
Kommentar
Fra : Mogens Hansen


Dato : 24-12-03 09:24


"Kåre Rasmussen" <mail@mail.dk> wrote:

> Jeg har lige kastet mig over programmering i C++ og har kigge lidt på
nogle
> tutorials. Nu er jeg flere gange faldet over %c, %d, %u o.lign.

Hvis du vil lære C++ programmering (ikke C) vil jeg anbefale at finde kilder
som bruger C++ på bedst muligt og ikke "blot" som en overbygning til C.
At bruge "printf" og den familie af funktioner anses i C++ for at være ikke
optimalt, bl.a. på grund af det manglende typecheck, manglende evne til
udvidelse og dårlig understøttelse for generisk programmering.
Som ofte vil man foretrække C++ stream biblioteket, som f.eks.
std::cout << "Hello World!" << std::endl;

Hvis en tutorial benytter "printf" i forbindelse med introduktion til C++
vil jeg umiddelbart anse det for at være et faresignal, der kan indikere at
der er andre steder hvor der muligvis er mangler.
Hvis ikke klasserne "std::string", "std::vector" og "std::map" bliver brugt
vil jeg se det som et faresignal.

Og det er jo svært for en der starter med C++ at vide.

En af de bedste introduktioner til C++ (som dog ikke er fuldstændigt
dækkende) er bogen
Accelerated C++
Andrew Koenig, Barbara E. Moo
ISBN 0-201-70353-X
Den er god for såvel folk der ved noget om programmering, men ikke kender
C++, som for folk der har brugt C++ i lang tid men ikke bruger klasser som
"std::string", "std::vector" og "std::map" ret meget.
Det er en fantastisk bog.

>
> Hvor kan jeg finde en forklaring på disse "værdier"
>
> Er printf en C eller C++ funktion?
>
> Og så lige det sidste:
> Som jeg ser det, skal man i C angive #include med .h (ex #include
> <stdio.h>), mens C++ accepterer #include <string>
>
> Er der et sted, hvor dette er beskrevet?

Det er beskrevet i C++ Standarden - selvom det ikke er det mest tilgængelige
sted.
Et bedre sted er bogen
The C++ Programming Language, Special Edition (alternativt Third Edition)
Bjarne Stroustrup
ISBN 0-201-70073-5 (Third: 0-201-88954-4)
side 821, kapitel B.3.1

Og dermed blev 2 af de væsentligste bøger atter nævnt, mens julestemningen
bredte sig.

Glædelig jul.

Venlig hilsen

Mogens Hansen



Kasper (29-12-2003)
Kommentar
Fra : Kasper


Dato : 29-12-03 01:40

> Hvis du vil lære C++ programmering (ikke C) vil jeg anbefale at finde
kilder
> som bruger C++ på bedst muligt og ikke "blot" som en overbygning til C.
> At bruge "printf" og den familie af funktioner anses i C++ for at være
ikke
> optimalt, bl.a. på grund af det manglende typecheck, manglende evne til
> udvidelse og dårlig understøttelse for generisk programmering.
> Som ofte vil man foretrække C++ stream biblioteket, som f.eks.
> std::cout << "Hello World!" << std::endl;

Hey

ved ikke om det er tilfældet at spørgeren ved et uheld har sammenlignet c++
og c, for i c, som der bruges i uC er det jo printf der bruges... men newer
mind, er det c++, ja så er cout jo bedre

KAsper



Byrial Jensen (07-01-2004)
Kommentar
Fra : Byrial Jensen


Dato : 07-01-04 22:03

Mogens Hansen wrote:
>
> At bruge "printf" og den familie af funktioner anses i C++ for at være ikke
> optimalt, bl.a. på grund af det manglende typecheck, manglende evne til
> udvidelse og dårlig understøttelse for generisk programmering.
> Som ofte vil man foretrække C++ stream biblioteket, som f.eks.
> std::cout << "Hello World!" << std::endl;

printf har dog en væsentlig fordel, nemlig at det er nemt at oversætte
et programs brugergrænseflade til et nyt (menneske-)sprog ved at
oversætte formatstrenge. F.eks.:

printf (ngettext ("Found %u error", "Found %u errors", no_of_errors),
no_of_errors);

Her vil kaldet til ngettext() returnere en formatstreng på det sprog som
brugeren har valgt på kørselstidspunktet (eller en af de engelske
tekster hvis teksten ikke er oversat til det valgte sprog). Teksten vil
endda være tilpasset efter det konkrete antal fejl efter regler
specificeret af oversætteren til det valgte sprog.

Når man oversætter formatstrenge, kan man frit bytte rundt på de enkelte
elementer i strengen for at opfylde de krav til ordstilling som det
sprog man oversætter til, har.

Man kunne også skrive:

std::cout << gettext ("Found ") << no_of_errors
<< ngettext (" error", " errors", no_of_errors);


Men det virker ikke godt for:
- Måske skal rækkefølgen af de tre elementer i udskriften være
anderledes på det valgte sprog.
- Måske skal "error" kasusbøjes og oversætteren kan ikke se sammenhængen.
- Måske skal udsagnsordet bøjes efter tal.
- Find selv på flere ...

Jeg vil gerne høre om du har et forslag til hvordan sådanne
lokaliseringsproblemer kan løses uden at bruge de i denne sammenhæng
praktiske printf-formatstrenge.


Mogens Hansen (08-01-2004)
Kommentar
Fra : Mogens Hansen


Dato : 08-01-04 19:42

"Byrial Jensen" <bjensen@nospam.dk> wrote:

[8<8<8<]
> Jeg vil gerne høre om du har et forslag til hvordan sådanne
> lokaliseringsproblemer kan løses uden at bruge de i denne sammenhæng
> praktiske printf-formatstrenge.

Det korte svar:
Boost.Format (www.boost.org)



Det lange svar:

Internationalisering og lokalisering af en applikation er et stort og
komplekst område.
Se bogen
Standard C++ IOStreams and Locales
Angelika Langer, Klaus Kreft
ISBN 0-201-18395-1
Part III, Internationalization, side 251-342 for en gennemgang af hvilke
faciliteter C++ stream biblioteket har.

Formatstrengen til printf i C indeholder 2 (faktisk 3) informationer:
* hvilken type der skal indsættes
* hvor den variable tekst skal indsættes
samt at der er en implicit, hårdkodet sammenhæng rækkefølgen som de indsatte
tekster skal stå i og rækkefølgen parametrene til printf.

Vi er formodentlig enige om at det er en fordel, hvis man ikke har mulighed
for at lave type mismatch, som man kan med printf.

Spørgsmålet er om formatstrengen til printf i C er tilstrækkelig fleksibel.
Man kan forestille sig at hvis udskrivningen tager flere variable, så har
man sommetider brug for at bytte om på rækkefølgen i forskellige talte
sprog.
F.eks. har tysk sommetider en anden ordstilling end dansk.

Så den eneste, for sammenhængen, nyttige egenskab som printf formatstrengen
har er angivelsen af hvor den variable tekst skal indsættes.

Microsoft har i .NET designet, hvad der svarer til printf formatstrengen,
således at man ikke angiver typen men blot parameter nummeret, og givet
mulighed for at ændre på rækkefølgen som parametrene kommer ud i den
endelige tekst.
I C# (og naturligvis tilsvarende i de øvrige .NET sprog) kan man skrive
Console.WriteLine("{0} {1}!", "Hello", "World");
hvor {0} angiver første variabel til output.
Man har mulighed for at lade en parameter optræde flere gange ved blot at
gentage {1} flere steder i formatstrengen, eller helt undlade at vise en
parameter.
..NET WriteLine er ikke bruger udvidelig med hensyn til hvilke typer den kan
udskrive. Det svarer til printf i C, og er således mere begrænset end stream
biblioteket i C++.

Noget svarende til hvad der findes i .NET er direkte tilgængeligt i C++ ved
hjælp af Boost.Format (www.boost.org).
Man man således i C++ skrive
cout << boost::format("%1% %2%!") % "Hello" % "World";
Naturligvis er det typesikkert og udvideligt med hensyn til typer, på samme
måde som C++ streams generelt.

Med en sådan løsning har man mulighed for at have den fleksibilitet i
forbindelse med oversættelse som du efterspurgte, samtidig med at man har
fuld typesikkerhed og mulighed for udvidelser med hensyn til hvilke typer
der kan udskrives.
Altså de bedste egenskaber fra C, C++ og C# slået sammen - hvis man har
brug for det.


Men der skal mere til at oversætte en applikation til flere talte sprog og
lokationer:

Hvordan håndterer printf f.eks. at man nogen steder bruger '.' og andre
steder ',' som decimal seperator, at 1000 separatorer er forskellige rundt
om i verden, at penge beløb og tidspunkter skrives forskelligt rundt om i
verden ?

Dertil kommer at der ofte indgår en GUI i en applikationen der skal
internationaliseres.
I C og C++ gør det naturligvis at man har brug for hjælp fra det bibliotek,
som man har benyttet til at lave GUI'en med.

Venlig hilsen

Mogens Hansen








Byrial Jensen (08-01-2004)
Kommentar
Fra : Byrial Jensen


Dato : 08-01-04 22:06

Mogens Hansen wrote:
> "Byrial Jensen" <bjensen@nospam.dk> wrote:
>
>>Jeg vil gerne høre om du har et forslag til hvordan sådanne
>>lokaliseringsproblemer kan løses uden at bruge de i denne sammenhæng
>>praktiske printf-formatstrenge.
>
> Det korte svar:
> Boost.Format (www.boost.org)
>
> Det lange svar:
>
> Internationalisering og lokalisering af en applikation er et stort og
> komplekst område.
> Se bogen
> Standard C++ IOStreams and Locales
> Angelika Langer, Klaus Kreft
> ISBN 0-201-18395-1
> Part III, Internationalization, side 251-342 for en gennemgang af hvilke
> faciliteter C++ stream biblioteket har.
>
> Formatstrengen til printf i C indeholder 2 (faktisk 3) informationer:
> * hvilken type der skal indsættes
> * hvor den variable tekst skal indsættes
> samt at der er en implicit, hårdkodet sammenhæng rækkefølgen som de indsatte
> tekster skal stå i og rækkefølgen parametrene til printf.

Rækkefølgen er ikke nødvendigvis implicit. Den kan også være eksplicit,
således at en oversætter af en formatstreng også kan ændre rækkefølgen.
Disse 2 printf-kald er ekvivalente:

printf ("%d %s", 1, "tekst");
printf ("%2$d %1$s", "tekst", 1);

Notationen er dog ikke specificeret C99, men i POSIX så vidt jeg ved
(korrektioner modtages gerne).


> Vi er formodentlig enige om at det er en fordel, hvis man ikke har mulighed
> for at lave type mismatch, som man kan med printf.

Bestemt. Jeg kender udmærket eksempler på lokaliserede programmer som er
gået ned fordi en oversætter er kommet til at ændre i type-angivelserne
i en formatstreng.

> Spørgsmålet er om formatstrengen til printf i C er tilstrækkelig fleksibel.
> Man kan forestille sig at hvis udskrivningen tager flere variable, så har
> man sommetider brug for at bytte om på rækkefølgen i forskellige talte
> sprog.

Det kan gøres. Se ovenfor.

> ..NET WriteLine er ikke bruger udvidelig med hensyn til hvilke typer den kan
> udskrive. Det svarer til printf i C, og er således mere begrænset end stream
> biblioteket i C++.

printf i GNU libc kan udvides med nye typer. Desværre er det ikke portabelt.

> Noget svarende til hvad der findes i .NET er direkte tilgængeligt i C++ ved
> hjælp af Boost.Format (www.boost.org).
> Man man således i C++ skrive
> cout << boost::format("%1% %2%!") % "Hello" % "World";
> Naturligvis er det typesikkert og udvideligt med hensyn til typer, på samme
> måde som C++ streams generelt.
>
> Med en sådan løsning har man mulighed for at have den fleksibilitet i
> forbindelse med oversættelse som du efterspurgte, samtidig med at man har
> fuld typesikkerhed og mulighed for udvidelser med hensyn til hvilke typer
> der kan udskrives.
> Altså de bedste egenskaber fra C, C++ og C# slået sammen - hvis man har
> brug for det.

Bestemt. Det ser fornuftigt ud. Tak for henvisningen, jeg vil kigge
nærmere på boost::format.

> Men der skal mere til at oversætte en applikation til flere talte sprog og
> lokationer:
>
> Hvordan håndterer printf f.eks. at man nogen steder bruger '.' og andre
> steder ',' som decimal seperator, at 1000 separatorer er forskellige rundt
> om i verden,

Man sætter blot LC_NUMERIC lokalet som printf() bruger.

> at penge beløb

Man bruger LC_MONETARY lokalet.

> og tidspunkter

Man sættter LC_TIME lokalet og bruger strftime().

> skrives forskelligt rundt om i verden ?


Mogens Hansen (08-01-2004)
Kommentar
Fra : Mogens Hansen


Dato : 08-01-04 22:55

"Byrial Jensen" <bjensen@nospam.dk> wrote:

[8<8<8<]
> Rækkefølgen er ikke nødvendigvis implicit. Den kan også være eksplicit,
> således at en oversætter af en formatstreng også kan ændre rækkefølgen.
> Disse 2 printf-kald er ekvivalente:
>
> printf ("%d %s", 1, "tekst");
> printf ("%2$d %1$s", "tekst", 1);
>
> Notationen er dog ikke specificeret C99, men i POSIX så vidt jeg ved
> (korrektioner modtages gerne).

Den kendte jeg ikke.
Det er også lige spørgsmålet hvad vi snakker om - er det C99, C++98 eller
POSIX ?

Jeg kan konstatere at det ikke virker med Borland C++Builder V6 og Microsoft
Visual C++ .NET 2003 på MS-Windows.
Derimod virker det med gcc 3.2 og Borland Kylix V3 for C++ på Linux.

[8<8<8<]
> > at penge beløb
>
> Man bruger LC_MONETARY lokalet.

Hvordan ved printf at det er et penge beløb og ikke bare en integer eller
float man skriver ?

>
> > og tidspunkter
>
> Man sættter LC_TIME lokalet og bruger strftime().

Hvordan passer det sammen med printf og format strenge ?

Venlig hilsen

Mogens Hansen



Byrial Jensen (09-01-2004)
Kommentar
Fra : Byrial Jensen


Dato : 09-01-04 20:27

Mogens Hansen wrote:
> "Byrial Jensen" <bjensen@nospam.dk> wrote:
>
>>Rækkefølgen er ikke nødvendigvis implicit. Den kan også være eksplicit,
>>således at en oversætter af en formatstreng også kan ændre rækkefølgen.
>>Disse 2 printf-kald er ekvivalente:
>>
>> printf ("%d %s", 1, "tekst");
>> printf ("%2$d %1$s", "tekst", 1);
>>
>>Notationen er dog ikke specificeret C99, men i POSIX så vidt jeg ved
>>(korrektioner modtages gerne).
>
> Den kendte jeg ikke.
> Det er også lige spørgsmålet hvad vi snakker om - er det C99, C++98 eller
> POSIX ?

C99 kender ikke %n$. Min man-side siger at notationen stammer fra Single
Unix Specification som er en udvidelse af POSIX (eller er SUS og POSIX
slået sammen nu?).

>>>at penge beløb
>>
>>Man bruger LC_MONETARY lokalet.
>
> Hvordan ved printf at det er et penge beløb og ikke bare en integer eller
> float man skriver ?

Det ved printf() ikke. Beløbsformatteringen laves strfmon().

#include <locale.h>
#include <monetary.h>
#include <stdio.h>

int main ()
{
setlocale (LC_ALL, "");
double value = 56.789;
char valuestr[48];
if (strfmon (valuestr, sizeof valuestr,
"%n (internationalt: %i)", value, value) < 0)
{
puts ("strfmon(): string too small");
return 1;
}
printf ("Prisen er %s\n", valuestr);
return 0;
}

$ LC_ALL=da_DK ./a.out
Prisen er kr 56,79 (internationalt: DKK 56,79)
$ LC_ALL=en_US ./a.out
Prisen er $56.79 (internationalt: USD 56.79)
$

>>>og tidspunkter
>>
>>Man sættter LC_TIME lokalet og bruger strftime().
>
> Hvordan passer det sammen med printf og format strenge ?

Man starter med at formattere tidspunktet med strftime() (svarende til
brugen strfmon() ovenfor), og kombinerer så efterfølgende tidspunktet
med resten af ens tekst i printf().

Der er dog problemer med manglende mulighed for kasusbøjning af
tidspunktet i nogle sprog og med brug af store/små begyndelsesbogstaver
i nogle tilfælde.


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

Månedens bedste
Årets bedste
Sidste års bedste