Portál AbcLinuxu, 12. května 2025 05:44

Dotaz: C makro na spocitani delky retezce

21.4.2010 18:33 jirik
C makro na spocitani delky retezce
Přečteno: 571×
Odpovědět | Admin
Dobry den,

rad bych se zeptal jestli jde v C nebo C++ napsat makro, kde by preprocesor spocital delku const char* retezce a vratil cislo.

Samozrejme nemam na mysli neco takoveho #define len(str) strlen(str)

Jde mi jen o to abych nemusel rucne doplnovat delky retezcu do kodu.

Dekuji za odpoved.

Řešení dotazu:


Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

21.4.2010 19:15 Sten
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
Odpovědět | | Sbalit | Link | Blokovat | Admin
V C++ to jde udělat přes šablony, protože ve skutečnosti je to const char[délka].

O existenci makra ale pochybuji.
Řešení 1× (jirik (tazatel))
21.4.2010 19:17 Sinuhet | skóre: 31
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
Odpovědět | | Sbalit | Link | Blokovat | Admin

Nejde. Ale muzete to udelat bud pomoci sizeof, nebo sablon.

#include <iostream>
#include <cstddef>

template<std::size_t N_>
std::size_t length(const char (&s)[N_])
{
        return N_;
}

int main(int argc, char** argv)
{
        const char str[] = "Hello World!";

        std::cout << sizeof(str) << ", " << length(str) << "\n";
        std::cout << sizeof("Hello World!") << ", " << length("Hello World!") << "\n";

        return 0;
}

(Pozn.: oba dva zpusoby vraceji delku retezce vcetne ukoncovaciho null, tzn. o jednicku vetsi, nez co dava strlen().)

21.4.2010 19:41 jirik
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
Dekuji za odpoved.

Sablony pouzivat nechci ale ten sizeof je super. Ten me vazne nenapadl.
21.4.2010 21:36 ::: | skóre: 14 | blog: e_lama
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
pozor, sizeof vrati spravne velikost jenom pokud je promena deklarovana jako pole, ne pokud je to ukazatel:
#include <iostream>

int main()
{
        char const *x = "Hello world!";
        
        std::cout << x << ", " << sizeof(x) << "\n";
}
vypise velikost ukazatele, ne delku retezce!
22.4.2010 11:35 lukas
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
Tvoj kod nie je najlepsi, pretoze sa spolieha na velkost typu char 8 bitov. Prenositelna verzia:
   ...
   const char str[] = "Hello World!";
   std::cout << sizeof(str)/sizeof(*str) << ", " << length(str) << "\n";
   ...
22.4.2010 11:49 FooBar
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
Omlouvam se, ale nemuzu nezareagovat. Tohle je pitomost. C standard absolutne a nedvojznacne urcuje, ze char ma velikost 1B. Jeho kod je prenositelny vzdy a vsude.

Samozrejme, do budoucna je to spravna praktika, ponevadz si clovek zvykne na to, ze nemuze definitivne predvidat velikost datovejch typu, nicmene v tomhle pripade je jeho kod zcela bez vyhrad na prenositelnost nebo cokoliv jinyho korektni.

(A pokud pises na exotickou platformu, ktera ma 1B velkej treba 9 bitu, tak te to furt netrapi, ponevadz sizeof pocita s byty a ne bity)
22.4.2010 10:31 chochi | skóre: 29 | Praha
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
Odpovědět | | Sbalit | Link | Blokovat | Admin
A proc nepouzit strlen? Pokud to prekladas rozumnym prekladacem s dostatecnou optimalizaci, tak se to vyoptimalizuje samo :-) pr.:

$ cat ll.c 
#include <string.h>

#define  STRLEN(x)      strlen(x)

int main() {
        return STRLEN("rozedeleny retezec" "neurcite delky");
}
$ ~/src/llvm/Debug/bin/clang -O2 -S ll.c -o -
        .file   "ll.c"
        .text
        .globl  main
        .align  16, 0x90
        .type   main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        movl    $32, %eax
        popl    %ebp
        ret
.Ltmp0:
        .size   main, .Ltmp0-main


        .section        .note.GNU-stack,"",@progbits
$ gcc -O2 -S ll.c -o -
        .file   "ll.c"
        .text
        .p2align 4,,15
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        movl    $32, %eax
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
        .section        .note.GNU-stack,"",@progbits
Pro ty co nemaji radi assembler - nikde se nevola funkce strlen, ale rovnou se vrati konstanta 32 (delka retezce) v instrukci
movl $32, %eax
24.4.2010 02:17 Nikola Pajkovský | skóre: 16
Rozbalit Rozbalit vše Re: C makro na spocitani delky retezce
:)
Save the whales. Feed the hungry. Free the mallocs

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.