abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
eParkomat, startup z ČR, postoupil mezi finalisty evropského akcelerátoru ChallengeUp!
Robot na pivo mu otevřel dveře k opravdovému byznysu
Internet věcí: Propojený svět? Už se to blíží...
dnes 15:00 | Zajímavý software

Stop motion je technika animace, při níž je reálný objekt mezi jednotlivými snímky ručně upravován a posouván o malé úseky, tak aby po spojení vyvolala animace dojem spojitosti. Jaký software lze pro stop motion použít na Linuxu? Článek na OMG! Ubuntu! představuje Heron Animation. Ten bohužel podporuje pouze webové kamery. Podpora digitálních zrcadlovek je začleněna například v programu qStopMotion.

Ladislav Hagara | Komentářů: 0
včera 21:21 | Nová verze Ladislav Hagara | Komentářů: 0
včera 11:44 | Zajímavý projekt

Na Indiegogo byla spuštěna kampaň na podporu herní mini konzole a multimediálního centra RetroEngine Sigma od Doyodo. Předobjednat ji lze již od 49 dolarů. Požadovaná částka 20 000 dolarů byla překonána již 6 krát. Majitelé mini konzole si budou moci zahrát hry pro Atari VCS 2600, Sega Genesis nebo NES. Předinstalováno bude multimediální centrum Kodi.

Ladislav Hagara | Komentářů: 0
včera 00:10 | Nová verze

Byla vydána verze 4.7 redakčního systému WordPress. Kódové označením Vaughan bylo vybráno na počest americké jazzové zpěvačky Sarah "Sassy" Vaughan. Z novinek lze zmínit například novou výchozí šablonu Twenty Seventeen, náhledy pdf souborů nebo WordPress REST API.

Ladislav Hagara | Komentářů: 4
6.12. 12:00 | Zajímavý projekt

Projekt Termbox umožňuje vyzkoušet si linuxové distribuce Ubuntu, Debian, Fedora, CentOS a Arch Linux ve webovém prohlížeči. Řešení je postaveno na projektu HyperContainer. Podrobnosti v často kladených dotazech (FAQ). Zdrojové kódy jsou k dispozici na GitHubu [reddit].

Ladislav Hagara | Komentářů: 27
6.12. 11:00 | Bezpečnostní upozornění

Byly zveřejněny informace o bezpečnostní chybě CVE-2016-8655 v Linuxu zneužitelné k lokální eskalaci práv. Chyba se dostala do linuxového jádra v srpnu 2011. V upstreamu byla opravena minulý týden [Hacker News].

Ladislav Hagara | Komentářů: 2
5.12. 22:00 | Komunita

Přibližně před měsícem bylo oznámeno, že linuxová distribuce SUSE Linux Enterprise Server (SLES) běží nově také Raspberry Pi 3 (dokumentace). Obraz verze 12 SP2 pro Raspberry Pi 3 je ke stažení zdarma. Pro registrované jsou po dobu jednoho roku zdarma také aktualizace. Dnes bylo oznámeno, že pro Raspberry Pi 3 je k dispozici také nové openSUSE Leap 42.2 (zprávička). K dispozici je hned několik obrazů.

Ladislav Hagara | Komentářů: 6
5.12. 06:00 | Zajímavý software

OMG! Ubuntu! představuje emulátor terminálu Hyper (GitHub) postavený na webových technologiích (HTML, CSS a JavaScript). V diskusi k článku je zmíněn podobný emulátor terminálu Black Screen. Hyper i Black Screen používají framework Electron, stejně jako editor Atom nebo vývojové prostředí Visual Studio Code.

Ladislav Hagara | Komentářů: 50
5.12. 06:00 | Zajímavý článek

I letos vychází řada ajťáckých adventních kalendářů. QEMU Advent Calendar 2016 přináší každý den nový obraz disku pro QEMU. Programátoři se mohou potrápit při řešení úloh z kalendáře Advent of Code 2016. Kalendáře Perl Advent Calendar 2016 a Perl 6 Advent Calendar přinášejí každý den zajímavé informace o programovacím jazyce Perl. Stranou nezůstává ani programovací jazyk Go.

Ladislav Hagara | Komentářů: 10
3.12. 16:24 | Nová verze

Byla vydána Mageia 5.1. Jedná se o první opravné vydání verze 5, jež vyšla v červnu loňského roku (zprávička). Uživatelům verze 5 nepřináší opravné vydání nic nového, samozřejmě pokud pravidelně aktualizují. Vydání obsahuje všechny aktualizace za posledního téměř půldruhého roku. Mageia 5.1 obsahuje LibreOffice 4.4.7, Linux 4.4.32, KDE4 4.14.5 nebo GNOME 3.14.3.

Ladislav Hagara | Komentářů: 17
Kolik máte dat ve svém domovském adresáři na svém primárním osobním počítači?
 (32%)
 (24%)
 (29%)
 (7%)
 (5%)
 (3%)
Celkem 790 hlasů
 Komentářů: 50, poslední 29.11. 15:50
Rozcestník
Reklama

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

22.9.2008 01:53 bojk
Spojení řetězců v c++
Přečteno: 7459×
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: 32
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: 23 | 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: 23 | 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: 71
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: 71
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: 71
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: 71
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: 71
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: 66
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: 66
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: 71
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: 66
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: 71
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.