abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    včera 22:44 | IT novinky

    IBM kupuje společnost HashiCorp (Terraform, Packer, Vault, Boundary, Consul, Nomad, Waypoint, Vagrant, …) za 6,4 miliardy dolarů, tj. 35 dolarů za akcii.

    Ladislav Hagara | Komentářů: 3
    včera 15:55 | Nová verze

    Byl vydán TrueNAS SCALE 24.04 “Dragonfish”. Přehled novinek této open source storage platformy postavené na Debianu v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    včera 13:44 | IT novinky

    Oznámeny byly nové Raspberry Pi Compute Module 4S. Vedle původní 1 GB varianty jsou nově k dispozici také varianty s 2 GB, 4 GB a 8 GB paměti. Compute Modules 4S mají na rozdíl od Compute Module 4 tvar a velikost Compute Module 3+ a předchozích. Lze tak provést snadný upgrade.

    Ladislav Hagara | Komentářů: 0
    včera 04:44 | Nová verze

    Po roce vývoje od vydání verze 1.24.0 byla vydána nová stabilní verze 1.26.0 webového serveru a reverzní proxy nginx (Wikipedie). Nová verze přináší řadu novinek. Podrobný přehled v souboru CHANGES-1.26.

    Ladislav Hagara | Komentářů: 0
    včera 04:33 | Nová verze

    Byla vydána nová verze 6.2 živé linuxové distribuce Tails (The Amnesic Incognito Live System), jež klade důraz na ochranu soukromí uživatelů a anonymitu. Přehled změn v příslušném seznamu. Tor Browser byl povýšen na verzi 13.0.14.

    Ladislav Hagara | Komentářů: 0
    včera 04:22 | Nová verze

    Byla vydána nová verze 30.0.0 frameworku pro vývoj multiplatformních desktopových aplikací pomocí JavaScriptu, HTML a CSS Electron (Wikipedie, GitHub). Chromium bylo aktualizováno na verzi 124.0.6367.49, V8 na verzi 12.4 a Node.js na verzi 20.11.1. Electron byl původně vyvíjen pro editor Atom pod názvem Atom Shell. Dnes je na Electronu postavena celá řada dalších aplikací.

    Ladislav Hagara | Komentářů: 2
    včera 04:11 | Nová verze

    Byla vydána nová verze 9.0.0 otevřeného emulátoru procesorů a virtualizačního nástroje QEMU (Wikipedie). Přispělo 220 vývojářů. Provedeno bylo více než 2 700 commitů. Přehled úprav a nových vlastností v seznamu změn.

    Ladislav Hagara | Komentářů: 0
    23.4. 23:22 | IT novinky

    Evropský parlament dnes přijal směrnici týkající se tzv. práva spotřebitele na opravu. Poslanci ji podpořili 584 hlasy (3 bylo proti a 14 se zdrželo hlasování). Směrnice ujasňuje povinnosti výrobců opravovat zboží a motivovat spotřebitele k tomu, aby si výrobky nechávali opravit a prodloužili tak jejich životnost.

    Ladislav Hagara | Komentářů: 9
    23.4. 16:11 | Nová verze

    Bylo oznámeno (cs) vydání Fedora Linuxu 40. Přehled novinek ve Fedora Workstation 40 a Fedora KDE 40 na stránkách Fedora Magazinu. Současně byl oznámen notebook Slimbook Fedora 2.

    Ladislav Hagara | Komentářů: 24
    23.4. 13:44 | Upozornění

    ČTK (Česká tisková kancelář) upozorňuje (X), že na jejím zpravodajském webu České noviny byly dnes dopoledne neznámým útočníkem umístěny dva smyšlené texty, které nepocházejí z její produkce. Jde o text s titulkem „BIS zabránila pokusu o atentát na nově zvoleného slovenského prezidenta Petra Pelligriniho“ a o údajné mimořádné prohlášení ministra Lipavského k témuž. Tyto dezinformace byly útočníky zveřejněny i s příslušnými notifikacemi v mobilní aplikaci Českých novin. ČTK ve svém zpravodajském servisu žádnou informaci v tomto znění nevydala.

    Ladislav Hagara | Komentářů: 29
    KDE Plasma 6
     (72%)
     (9%)
     (2%)
     (17%)
    Celkem 723 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Dotaz: Spojení řetězců v c++

    22.9.2008 01:53 bojk
    Spojení řetězců v c++
    Přečteno: 8673×
    Začínám programovat a nevím jak spojit řetězce v c++. Zkoušel jsem funkci strcat, ale tam mi spojí jen strcat(ret1,"n"), nikoliv strcat(ret1,ret2) nebo spojí ale nemůžu to přečíst. Pokud to spojený je, jak se to dá přečíst?

    Odpovědi

    Gogulux avatar 22.9.2008 06:29 Gogulux | skóre: 3 | blog: WTF
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    22.9.2008 08:10 frr | skóre: 34
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    V C++ by měl fungovat operátor "+", ne? A taky "+=" .

    string a,b,c;

    a = b + c; // jedna moznost

    a += b; // jina moznost

    Jedná se skutečně o C++? Nebo děláš v holém "C" a tvoje "řetězce" jsou typu char* ?
    [:wq]
    22.9.2008 11:43 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Možná je to jen C, překládám pomocí gcc. Problém je ten, že třeba a+b vrátí c, tj sečte to. Řetězce jsou char.
    22.9.2008 13:00 luky
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++

    Jak uvedl kolega vyse, retezce typu string (v c++) lze scitat. Pro C-ckovske retezece (char *) musite alokovat pamet (nebo proste nejak pripravit zapisovatelny dostatecne velky cilovy buffer), viz nize.

    char *mystrcat(char *str1, char *str2)
    {
    	char *str;
    
    	if (!str1) str1 = "";
    	if (!str2) str2 = "";
    	str = malloc(strlen(str1) + strlen(str2) + 1);
    	if (str) sprintf(str, "%s%s", str1, str2);
    	return str;
    }
    
    ...
    char *a = "prvni";
    char *b = "druhy";
    char *c = mystrcat(a, b);
    printf("cat: %s\n", c);
    free(c);
    ...
    

    22.9.2008 12:14 JS
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Pokud se nepletu, tak funkce strcat vyzaduje, aby v cilovem retezci (kam se spojuje) bylo dost mista pro oba dva. Neni to nahodou ten problem? Obecne u C retezcovych funkci plati, ze si musite vsechnu alokaci/dealokaci provadet sam.

    Jinak, asi bych mel vysvetlit vyse uvedene komentare - moderni C++ ma ve sve standardni knihovne jiny typ retezcu nez char *, ktere pochazeji z C.
    Luboš Doležel (Doli) avatar 22.9.2008 12:44 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Ukažte nám zdroják, z tohoto není jasné, co vlastně provádíte. )Zdroják přiložte jako přílohu nepo uzavřete do HTML tagu <pre>.)
    22.9.2008 13:20 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Už jsem to vyřešil. Snažil jsem se přidávat písmena do řetězce.
        while(1) {
          buf[i] = getdata();
          if (buf[i] == '\n') {
            break;
          }
          i++;
        }
        buf[i+1] = 0;
    
    22.9.2008 13:25 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Takhle už řetězec vypíšu, ale stejně mi nefunguje podmínka: if (buf == "napis1") se neprovede, ale když vypisuju buf, tak se rovna napis1.
    22.9.2008 14:04 Messa | skóre: 39 | blog: Messa
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    C je nízkoúrovňový jazyk (C++ už tolik ne, ale tam zase nejsou přetížené operátory pro char*). Když napíšeš buf == "napis", tak neporovnáváš obsah řetězce buf s druhým řetězcem, ale porovnáváš pointer buf (tedy adresu kam míří) s adresou umístění statického řetězce "napis", který je umístěn někde úplně jinde. Není to prostě "hluboké" porovnávání, jen porovnávání adres. Musíš použít něco jako strcmp.

    Kdyby to bylo v C++ a buf by byl std::string, pak by to fungovalo, protože tam tento operátor přetížen je.
    22.9.2008 14:05 Leshy | skóre: 4
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Jestli to nebude tím, že buf je ukazatel na ten řetězec. Takže vlastně porovnáváš ukazatel s nějakým textem. Pro porovnání musíš použít funkci int strcmp(char*, char*)
    22.9.2008 15:24 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Dík. Proč se ale následující provede pouze jednou, i když to mám v cyklu while? V dalších cyklech už totiž porovnání nefunguje, pouze v prvním.
      while (1) {
        i=0;
        while(1) {
          buf[i] = getdata();
          if (buf[i] == '1') {
            break;
          }
          i++;
        }
    
    if (!strcmp(buf,"l1")) {
      print("equal");
    }
    
      }
    
    22.9.2008 15:45 Boris Dušek | skóre: 22 | blog: everything
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Řetězce v C musí mít za posledním znakem speciální znak '\0' (jehož hodnota je skutečně nula) - tedy po načtení vstupu je nutné za poslední znak přidat '\0'. Konkrétně teda před poslední if dát buf[i+1]='\0'. Protože pokud je jednou načteno "llll1" a podruhé "l1", funkce strcmp uvidí, že data se shodují ve společné části (tedy "l1"), ale uvidí nakonec taky, že za "l1" v buf nenásleduje '\0', tedy že řetězec v buf za "l1" pokračuje ("l1ll1...") - takže ty řetězce nejsou shodné. Proto to může hrát roli.

    Stejně je ale kód nekorektní - nikde není prováděna kontrola toho, jestli se data nenačítají tak dlouho, že budou zapisovaná i mimo pamět pro buffer "buf". Takže pokud je buf zadeklarován něco jako char buf[BUFSIZE];, tak ještě je nutné přidat do prvního "if"u další kontrolu:

    if (buf[i] == '1' || i >= BUFSIZE - 1)

    O jedno méně proto, že na posledním znaku musí být '\0'.
    vim ~/.emacs
    22.9.2008 16:40 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Takto to stejně nefunguje.
    22.9.2008 17:01 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Už to jde. Ten parametr getdata získával data pomocí echo. Funguje to jen s pomocí echo -n;
    22.9.2008 17:40 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Teď by mě zas zajímalo, proč to nevypisuje poslední část řetězce? Došla mu paměť? Proč?
      if (!strcmp(buf,"s1on")) { print("zapinam zarizeni 1\n"); }
      if (!strcmp(buf,"s1off")) { print("vypinam zarizeni 1\n"); }
      if (!strcmp(buf,"s2on")) { print("zapinam zarizeni 2\n"); }
      if (!strcmp(buf,"s2off")) { print("vypinam zarizeni 2\n"); }
    
    Pokud dostane s2off, tak mi vypise jen "vypinam zarizeni". U ostatnich voleb to vypisuje vsechno.
    22.9.2008 17:50 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Nejenom to mrví print, nic za tím už nefunguje. Mám pocit, že strcmp má omezemý počet porovnání. Mám pravdu?
    22.9.2008 18:51 pht | skóre: 48 | blog: pht
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    nemate pravdu. mate tam nekde jinde chybu ktera prepisuje pamet. pak se to takhle projevi nekde kde to s tim vubec nesouvisi. kdyztak ukazte ten kod celej anebo jak psali jini, zkuste bud pracovat v c++ nebo jinem jazyce (bash, perl, ... je nutne to mit v c?), kde nemusite resit pamet, anebo si dejte kurz programovani v c.
    In Ada the typical infinite loop would normally be terminated by detonation.
    22.9.2008 17:56 vencas | skóre: 32
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Co je to print? Nemá to být printf? Pak to půjde.
    22.9.2008 17:58 vencas | skóre: 32
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    PS. Jestli je to opravdu v c++, tak se na tohle všechno vykašlete a použijde std::string, jak už tady bylo mnohokrát řečeno. Tam vám bude fungovat porovnávání ==, sčítání + a ušetříte si chyby, které tady v těch char* mezitím nasekáte. Může být užitečné se to sice naučit, ale jestli nakonec nebudete programovat v céčku (ale v c++), tak to zase _tolik_ užitečné nebude.
    22.9.2008 18:08 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tohle to je v C.
    22.9.2008 18:10 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tak trochu navazuju na http://www.abclinuxu.cz/poradna/programovani/show/239649#59. Je to programování jednočipu.
    void print (char *string){
      while (*string) {
      while (!(UCSRA & (1 << UDRE)));
      UDR = *string;
      string++;
      }
      string = 0;
      return;
    }
    
    22.9.2008 18:11 Boris Dušek | skóre: 22 | blog: everything
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Nic ti nebrání začít nejdřív místo "gcc" psát "g++" ;-), a pak začít používat std::string
    vim ~/.emacs
    22.9.2008 18:30 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Brání. Používám avr-gcc.
    22.9.2008 18:33 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tak nebrání. Použiju avr-g++.
    22.9.2008 18:41 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tak nic, avr-g++ nezná string;
    22.9.2008 18:53 pht | skóre: 48 | blog: pht
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    mozna pomuze #include <string>
    In Ada the typical infinite loop would normally be terminated by detonation.
    22.9.2008 18:55 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Nepomůže. <string> nezná. <string.h> ano, ale ten neobsahuje definici pro std, pro string.
    22.9.2008 18:56 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html
    22.9.2008 19:55 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tak jsem zjistil, že toto funguje:
    i = 1;
      if (i) {
        print("zapinam zarizeni 1\n");
        print("zapinam zarizeni 2\n");
        print("zapinam zarizeni 3\n");
        print("zapinam zarizeni 4\n");
        print("zapinam zarizeni 5\n");
        print("zapinam zarizeni 6\n");
      }
    
    ale toto už nevypíše všechny printy:
    print(buf)
    i = 1;
      if (i) {
        print("zapinam zarizeni 1\n");
        print("zapinam zarizeni 2\n");
        print("zapinam zarizeni 3\n");
        print("zapinam zarizeni 4\n");
        print("zapinam zarizeni 5\n");
        print("zapinam zarizeni 6\n");
      }
    
    Problém nastává, kdykoliv se snažím jakkoliv přečíst buf. Proč?
    22.9.2008 20:03 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    A záleží na velikosti buf kolik se toho pak vypíše.
    char buf[10]; - vypíše se potom toho víc než při char buf[20];
    
    Takže problém s pamětí. Jak to obejít?
    22.9.2008 20:13 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Zjistil jsem, že buf obsahuje kusy dalšího textu.
    i = ReceiveByte();
    
    buf[0] = 'a';
    buf[1] = 'n';
    buf[2] = 'o';
    buf[3] = 'n';
    buf[4] = 'y';
    buf[5] = 'm';
    buf[6] = 0;
    
    print(buf[0]);
    print(buf[1]);
    print(buf[2]);
    print(buf[3]);
    print(buf[4]);
    print(buf[5]);
    
      if (i) {
        print("zapinam zarizeni 1\n");
        print("zapinam zarizeni 2\n");
        print("zapinam zarizeni 3\n");
        print("zapinam zarizeni 4\n");
        print("zapinam zarizeni 5\n");
        print("zapinam zarizeni 6\n");
      }
    
    
    
    vrati:
    
    apinam zarizeni 1
    ni 1
    i 1
    ni 1
    am zarizeni 2
    eni 1
    zapinam zarizeni 1
    zapinam zarizeni 2
    zapinam zarizeni 3
    zapinam zarizeni 4
    zapinam zarizeni 5
    zapinam zarizeni 6
    apinam zarizeni 1
    ni 1
    i 1
    ni 1
    am zarizeni 2
    eni 1
    zapinam zarizeni 1
    zapinam zarizeni 2
    zapinam zarizeni 3
    zapinam zarizeni 4
    zapinam zarizeni 5
    zapinam zarizeni 6
    
    
    22.9.2008 20:45 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tak už vím, že problém dělá fce print.
        print("zapinam zarizeni 1\n");
        print("zapinam zarizeni 2\n");
        print("zapinam zarizeni 3\n");
        print("zapinam zarizeni 4\n");
        print("zapinam zarizeni 5\n");
        print("zapinam zarizeni 6\n");
    funguje, ale
    
        print("zapinam zarizeni 1\n");
        print("zapinam zarizeni 2\n");
        print("zapinam zarizeni 3\n");
        print("zapinam zarizeni 4\n");
        print("zapinam zarizeni 5\n");
        print("zapinam zarizeni 6\n");
        print("zapinam zarizeni 7\n");
    už ne
    
     void print (char string[20]){
       while (string[20]) {
       while (!(UCSRA & (1 << UDRE)));
       UDR = string[20];
       string++;
       }
       return;
       free(string);
     }
    
    Jak mam fci print upravit?
    22.9.2008 20:51 Jirka P.
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tak už vím, že problém dělá fce print.
     void print (char string[20]){
       while (string[20]) {
       while (!(UCSRA & (1 << UDRE)));
       UDR = string[20];
       string++;
       }
       return;
       free(string);
     }
    
    Jak mam fci print upravit?
    AUUUU!

    Vždyť jste sem posílal funkci print, která vypadala mnohem líp (taková ta s těma hvězdičkama bez těch hranatic). Doufám, že to celý nevzniklo jako produkt mechanického nahrazení "*string" za "string[20]", a jestli jo, tak to vraťte (aspoň v té funkci :-) )
    22.9.2008 20:58 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    To nepomůže, i ta původní s těma hvězdičkama dělala přesně tohle.
    22.9.2008 21:19 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    nějaký další nápad? Už fakt nevím co s tím.
    22.9.2008 21:43 Jirka P.
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Ale vypadala o hodně líp. V téhle verzi je string[20] špatně a free(string) taky špatně.

    Co s tím? Těžko říct. Ne proto, že by ty chyby byly neodhalitelné, ale spíš proto, že je jich moc a to jsme spoustu kódu ještě neviděli. Takhle to odlaďovat na jednočipu, když ještě navíc pořádně neznáte C, je peklo. Doporučil bych to, co jde, vyškubnout (nahradit interakci se sériovou linkou třeba putc()/getc()) a odladit to na PC kde máte debugger a valgrind.
    22.9.2008 21:49 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tady je kód:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define F_CPU 9216000UL // 9.216 MHz
    #include <util/delay.h>
    
    #define sbi(var, mask)   ((var) |= (1 << (mask)))
    #define cbi(var, mask)   ((var) &= ~(1 << (mask)))
    
    /* Prototypes */
    void InitUART (unsigned char baudrate);
    unsigned char ReceiveByte (void);
    void TransmitByte (unsigned char data);
    void print (char *string);
    unsigned char indata;
    int strcmp(char*, char*);
    
    int
    main (void)
    {
      char buf[20]; // may be more if longer strings expected
      int i, known, passed;
      InitUART (59);               /* Set the baudrate to 9600bps using a 9.216MHz crystal */
    
      sbi(DDRD, 2);
      sbi(DDRD, 3);
      sbi(DDRD, 4);
      sbi(DDRD, 5);
      sbi(DDRD, 6);
      sbi(DDRB, 3);
      PORTD = 0;
    
      while (1) {
    
        i = ReceiveByte();
    
        if (i) {
          print("zapinam zarizeni 1\n");
          print("zapinam zarizeni 2\n");
          print("zapinam zarizeni 3\n");
          print("zapinam zarizeni 4\n");
          print("zapinam zarizeni 5\n");
          print("zapinam zarizeni 6\n");
          print("zapinam zarizeni 7\n");
        }
    
      }
    
    
    }
    
    
    /* Initialize UART */
    void
    InitUART (unsigned char baudrate)
    {
      /* Set the baud rate */
      UBRRL = baudrate;
    
      /* Enable UART receiver and transmitter */
      UCSRB = (1 << RXEN) | (1 << TXEN);
    
      /* 8 data bits, 1 stop bit */
      UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
    
    }
    
    /* Read and write functions */
    unsigned char
    ReceiveByte (void)
    {
      /* Wait for incomming data */
      while (!(UCSRA & (1 << RXC)));
    
      /* Return the data */
      return UDR;
    }
    
    void
    TransmitByte (unsigned char data)
    {
      /* Wait for empty transmit buffer */
      while (!(UCSRA & (1 << UDRE)));
    
      /* Start transmittion */
      UDR = data;
    }
    
    void print (char *string){
      while (*string) {
      while (!(UCSRA & (1 << UDRE)));
      UDR = *string;
      string++;
      }
      string = 0;
      return;
    }
    
    (některé proměnné jsou zbytečné pozůstatky z různých pokusů)
    22.9.2008 22:49 Jirka P.
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    A co tahle verze dělá nebo nedělá? Nevidim tam nic špatnýho
    22.9.2008 22:55 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tohle vrací
    zarizeni 7
    zapinam zarizeni 2
    zapinam zarizeni 3
    zapinam zarizeni 4
    zapinam zarizeni 5
    zapinam zarizeni 6
    zapina
    
    Pokud přidám ještě jedno print, tak to nevrací nic a začne blikat dioda připojená k jednočipu, tudíš asi problém s pamětí či co. Pokud přidám dvě print, tak začne blikat víc diod a jednočip se "zasekne". Pomůže až přemazání a odpojení/připojení napájení.
    22.9.2008 23:12 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tento kód nemůže fungovat - důvod je popsán tady

    Quando omni flunkus moritati
    22.9.2008 23:21 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Doporučil bych to, co jde, vyškubnout (nahradit interakci se sériovou linkou třeba putc()/getc()) a odladit to na PC kde máte debugger a valgrind.
    Myšlenka je to pěkná, ale hodně chyb se na PC neprojeví (ta, která je v programu níže, je krásný příklad)
    Quando omni flunkus moritati
    22.9.2008 23:32 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Díky. Už to jde. Neměl jsem ani tušení že toto atmel umí.
          print(PSTR("zapinam zarizeni 1\n"));
          print(PSTR("zapinam zarizeni 2\n"));
          print(PSTR("zapinam zarizeni 3\n"));
          print(PSTR("zapinam zarizeni 4\n"));
          print(PSTR("zapinam zarizeni 5\n"));
          print(PSTR("zapinam zarizeni 6\n"));
          print(PSTR("zapinam zarizeni 7\n"));
          print(PSTR("zapinam zarizeni 8\n"));
          print(PSTR("zapinam zarizeni 9\n"));
          print(PSTR("zapinam zarizeni 10\n"));
          print(PSTR("zapinam zarizeni 11\n"));
          print(PSTR("zapinam zarizeni 12\n"));
    ....
    void print (char *string){
      char k;
      while ((k=pgm_read_byte(string++))>0) {
      while (!(UCSRA & (1 << UDRE)));
      UDR = k;
      }
      return;
    }
    
    Funguje bezvadně.
    23.9.2008 00:22 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Funguje to možná bezvadně, ale napsané je to špatně. Schválně zkus tohle:
    print(PSTR("zapínám zarízení 1\n"));
    Pokud se nepletu, tak už to tak bezvadně fungovat nebude.
    Quando omni flunkus moritati
    23.9.2008 10:02 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Jo tohle nejde. Proč?
    23.9.2008 10:37 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    k je deklarovaná jako char, to znamená číslo se znaménkem, rozsah -128 až +127. Znak 'í' má číselnou hodnotu 161, to se do rozsahu char nevejde a pro tvůj program tedy 'í' má význam -95. No a když se podíváš, co testuje to while, tak máš jasno, proč to nejde.
    Quando omni flunkus moritati
    23.9.2008 11:08 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Aha. Díky. Tak to se rovnou zeptám jak nejefektivněji rozdělit řetězec na tři podle mezer(než začnu zas výmýšlet blbosti). V php tohle dělá explode. V c nemám ani potuchy. Mám řetězec buf: "prvni druhy treti". Teď bych chtěl podmínku. Pokud je první slovo v buf prvni, proveď atd...
    23.9.2008 11:18 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Zkoušel jsem podle http://forums.neverside.com/thread/92405/, ale zaplní to skoro celý čip.
    23.9.2008 11:43 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Nicméně to funguje. Jen je zase problém s nedostatkem paměti. Jak mám dát něco z tý fce
    char ** explode(char separator, char *string)
    {
        int start = 0, i, k = 1, count = 2;
        char **strarr;
        
        for (i = 0; string[i] != '\0'; i++)
            /* how many rows do we need for our array? */
            if (string[i] == separator)
                count++;
        
        /* count is at least 2 to make room for the entire string
         * and the ending NULL */
        strarr = malloc(count * sizeof(char*));
        i = 0;
        
        while (*string++ != '\0')
        {
            if (*string == separator)
            {
                strarr[i] = malloc(k - start + 2);
                strncpy(strarr[i], string - k + start, k - start + 1);
                strarr[i][k - start + 1] = '\0'; /* guarantee null termination */
                start = k;
                i++;
            }
            k++;
        }
        /* copy the last part of the string after the last separator */
        strarr[i] = malloc(k - start);
        strncpy(strarr[i], string - k + start, k - start - 1);
        strarr[i][k - start - 1] = '\0'; /* guarantee null termination */
        strarr[++i] = NULL;
        
        return strarr;
    }
    
    Do flash?
    23.9.2008 13:34 bojk
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Problém je tady: strarr = explode(' ', buf);. Buf je plný a zaplňuje se strarr. Tudíš úzké místo na paměť. Dá se to omezení nějak omezit?
    24.9.2008 18:22 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    V tomhle ti moc neporadím.

    Část problému spočívá v tom malloc, jakmile ho někde použiješ, program se zvětší přibližně o 500B (o 600B, pokud nepoužíváš optimalizace). Na to hned navazuje nedostatek RAM paměti v tom procesoru všeobecně. Použití dynamické alokace paměti kus paměti sebere jenom na svou režii. Do toho přijdej, že char *string je taky uložen v paměti. No a nakonec ta rozdělená slova jsou taky uložena v paměti. Čiže: ten celý řetězec je tam v jednu chvíli uložen dvakrát, čímž se maximální délka rozdělitelného řetězce snižuje na nějakých 50B, možná ani to ne - každé slovo zabere 2B jenom tím, že na něj existuje ukazatel, volání funkcí potřebuje volnou paměť kvůli zásobníku (a ne málo) atd.

    Kde by se dalo ušetřit, je změnit tu funkci tak, aby vracela ukazatele do toho původního řetězce. Tedy
    char ** explode(char separator, char *string)
    {
        // Tenhle kus necháme
        int start = 0, i, k = 1, count = 2;
        char **strarr;
        
        for (i = 0; string[i] != '\0'; i++)
            /* how many rows do we need for our array? */
            if (string[i] == separator)
                count++;
        
        /* count is at least 2 to make room for the entire string
         * and the ending NULL */
        strarr = malloc(count * sizeof(char*));
        i = 0;
    
        // Tenhle kus změníme
        while (*string != '\0')
        {
            if (*string == separator)
            {
                strarr[i] = string;
                i++;
            }
            string++;
        }
    
        return strarr
    Kód je jen pro náhled, tak, jak je, možná nebude fungovat. Ale pozor! Tohle řešení používá pro původní řetězec i rozdělená slova stejnou paměť. Jinak řečeno když do funkce vrazíš string a změníš jedno z vrácených slov, pak se změní i string. A obráceně.

    Mnohem rozumnější ale bude pořídit si jiný čip, protože Attiny2313 není zrovna nejvhodnější pro laborování s jazykem C. Jakmile se pustíš do něčeho složitějšího (a to používání malloc určitě je), tak rychle dojde paměť. Docela levně se dá pořídit ATmega8, ta má 1kB RAM a 8kB flash, tam se chvíli vejdeš.

    Quando omni flunkus moritati
    Josef Kufner avatar 24.9.2008 21:05 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tohle nebude fungovat moc hezky, protože uložíš pointer na oddělovač a ne na začátek řetězce za oddělovačem.

    Lepší je nahradit oddělovač za '\0', tím se zakončí předchozí řetězec a uložit pointer na následující znak.

    Tedy:
        // Tenhle kus změníme
        while (*string != '\0')
        {
            if (*string == separator)
            {
                *string = 0;
                string++;
                strarr[i] = string;
                i++;
            }
            string++;
        }
    
    Pokud chceš komprimovanou verzi:
    char *p = string;
    i = 0;
     
    while ((p = strchr(p, separator))) {
       *p = 0;
       strarr[i++] = ++p;
    }
    
    ps: netestoval jsem to
    Hello world ! Segmentation fault (core dumped)
    Josef Kufner avatar 24.9.2008 21:19 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Možná bych to celé napsal jako:
    char ** explode(char *str, char separator)
    {
      char *p = str;
      i = 1;
      i_max = 16;   // obvykly maximalni pocet casti
      char ** buf = (char **) malloc(sizeof(char *), i_max);
     
      buf[0] = str; // cast pred prvnim oddelovacem
     
      while ((p = strchr(p, separator))) {
        *p = 0;
        buf[i++] = ++p;
     
        // alokace dalsi pameti, pokud nestaci na dalsi iteraci
        if (i == i_max) {
          i_max *= 2;
          buf = (char **) realloc(buf, i_max * sizeof(char *));
        }
      }
     
      buf[i] = NULL;    // zakonceni pole
      return buf;       // nezapomenout pak free(buf)
    }
    
    ps: ani nyni jsem to netestoval ;-)
    Hello world ! Segmentation fault (core dumped)
    24.9.2008 23:03 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Tohle nebude fungovat moc hezky, protože uložíš pointer na oddělovač a ne na začátek řetězce za oddělovačem.
    To je klidně možný, taky jsem říkal, že je to jenom pro náhled. Očekávám trochu invence ze strany tazatele, že si to překontroluje a opraví.
    Pokud chceš komprimovanou verzi:
    Tahle komprimovaná verze je možná z hlediska jazyka C hezky napsaná, ale zabere 74B (ten strchr stojí 40B), kdežto ta původní jenom 50B.
    Quando omni flunkus moritati
    Josef Kufner avatar 25.9.2008 01:59 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    No pokud to chce pro tak malý počítač, že záleží na rozdílu v desítkách bytů, tak bych to radši psal v assembleru ;-) (Nečetl jsem diskusi celou.) Ale možná by pomohla vlastní implementace strchr() :-D
    Hello world ! Segmentation fault (core dumped)
    25.9.2008 15:32 trekker.dk | skóre: 72
    Rozbalit Rozbalit vše Re: Spojení řetězců v c++
    Ten procesor má 2kB flash a 128B RAM. Jenom malloc a realloc v té funkci explode zaberou čtvrtinu té flash a to ten program ještě nic nedělá. Takže bych řekl, že na rozdílu v desítkách bytů na první pohled záleží, ale na druhý to možná bude jedno, protože ten program se stejně nevejde.

    S tím assemblerem souhlasím.
    Quando omni flunkus moritati

    Založit nové vláknoNahoru

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

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.