Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C] printf met 2 x time_t foutief

Pagina: 1
Acties:

  • honda4life
  • Registratie: Januari 2007
  • Laatst online: 22:22
Hallo iedereen,

Vast weer een beginnersfout, daarom heb ik even jullie hulp nodig:
Ik probeer het volgende:

C:
1
2
3
printf("time: %s\n", strftime_t("%H:%M", batchstatus[i].dt));
printf("date: %s\n", strftime_t("%Y%m%d", batchstatus[i].dt));
printf("time: %s date: %s\n", strftime_t("%H:%M", batchstatus[i].dt), strftime_t("%Y%m%d", batchstatus[i].dt));


Het vreemde is dat de printf met één maal de conversie perfect werkt > batchstatus[i].dt is dus correct lijkt me.
Wanneer ik zowel tijd en datum wil, krijg ik 2x de tijd:
time: 10:45
date: 20130202
time: 10:45 date: 10:45
Akkoord, ik dan in één conversie dit oplossen, maar dit is ook m'n debug test, in werkelijkheid wil ik het écht wel in twee keer nodig om netjes te zijn.


Als ik nog een bijkomende vraag mag stellen:
Hoe handel je op een nette manier strings af in c?
Voorlopig doe ik het als volgt:
C:
1
2
3
4
const int bufsize = 100;
char *buf = new char[bufsize];
//Later vaak als volgt gebruikt:
snprintf(buf , bufsize, "SystemId: %i", SystemID);

Is er zo niks handigs waar de lengte automatisch geregeld wordt? of niet als pointer is?

Bedankt!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Kun je er even de manual pages van strftime_t op naslaan om te zien welk geheugen strftime gebruikt?
Dan zou het een en ander al behoorlijk duidelijk moeten zijn...

spoiler:
strftime_t gebruikt waarschijnlijk statisch gealloceerd geheugen, dus:
oproep van strftime_t 1 vult de buffer in
oproep van strftime_t 2 overschijft de buffer met de nieuwe uitvoer
oproep van printf geeft 2 keer dezelfde statisch geallocaarde buffer mee.


Trouwens:
C++:
1
char *buf = new char[100]

is C++, geen C. (de new operator is C++).

In C++ gebruik je std::string. In C zit er niets anders op dan zelf je allocaties/deallocaties te doen met malloc/free. Eventueel kun je ze ook op de stack doen, maar dan moet je (zoals altijd trouwens) donders goed opletten dat je geen buffer overflows introduceert en dat je geen stack overflow creert; stacks zijn ook gelimiteerd in grootte.
C:
1
2
char buffer[100];
snprintf(buffer, 100, "SystemId: %d\n", SystemId);

[ Voor 39% gewijzigd door H!GHGuY op 03-02-2013 14:05 ]

ASSUME makes an ASS out of U and ME


  • evolution536
  • Registratie: Maart 2009
  • Laatst online: 05-06-2024

evolution536

besh besh

Als je graag bij C wilt blijven dan moet je de string als volgt behandelen:

C++:
1
2
3
4
5
char *buffer = malloc(100);

// doe dingen met je string...

free(buffer);

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 22:51

leuk_he

1. Controleer de kabel!

als ik zoek op strftime vind ik ook een versie waar je al eerste parameter een pointer to een character array moet opgeven net als sprintf. zoiets: (is een c tutorial)

http://www.java2s.com/Tutorial/C/0460__time.h/strftime.htm

blijkbaar gebruik jij een andere. Maar wat H!GHGuY hier boven beschrijft lijkt me dan ook de reden.

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


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

.oisyn

Moderator Devschuur®

Demotivational Speaker

leuk_he schreef op maandag 04 februari 2013 @ 14:56:
blijkbaar gebruik jij een andere.
Vandaar ook strftime_t() ;). Ik gok dat ie zo geimplementeerd is:

C:
1
2
3
4
5
char * strftime_t(const char *fmt, const struct tm *t)
{
    static char buf[100];
    return strftime(buf, 100, fmt, t);
}

[ Voor 36% gewijzigd door .oisyn op 04-02-2013 16:35 ]

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.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-11 03:08
Grote kans dat het zoiets is, maar eigenlijk is dat slecht, want als de format string dan onverwacht lang is of onverwacht lange uitvoer genereert, dan is de inhoud van de buffer ongedefinieerd.

Overigens returnt strftime() een size_t en geen pointer naar de buffer, dus daar moet eigenlijk return buf staan. Sowieso is strftime() enigzins ondergespecificeerd: als fmt="" en de functie return 0, is je buffer dan wel of niet correct geïnitialiseerd? En als je 0 terugkrijgt, betekent dat dan dat je buffer te klein was of dat er iets anders mis is?

De man-page geeft hier totaal geen uitsluitsel over, dus dit lijkt me het soort functie dat bijna onmogelijk correct te wrappen is. Waarschijnlijk is het dus makkelijker om direct strftime() met een voldoende ruime buffer te callen, maar dat is ook nog niet eenvoudig omdat die functie locale-afhankelijk is, en ik geen enkel idee heb hoe lang "Woensdag" in alle talen van de wereld is, bijvoorbeeld.

(Ter vergelijking: sprintf() is veel beter gespecificeerd.)




Overigens is het specifieke probleem uit de TS ook best zo op te lossen:

C:
1
fputs(strftime_t("time: %H:%M date: %Y%m%d\n", batchstatus[i].dt), stdout);
Pagina: 1