Databáze DuckDB (Wikipedie) byla vydána ve verzi 1.5.0. S kódovým názvem Variegata (husice rajská). Přináší řadu vylepšení, včetně nového ergonomičtějšího CLI klienta nebo podporu pro typ VARIANT a vestavěný typ GEOMETRY.
V pátek 6. a sobotu 7. března proběhl v pražském sídle Nejvyššího kontrolního úřadu (NKÚ) Hackathon veřejné správy 7.1. Publikovány byly vytvořené aplikace. V kategorii projektů rozvíjených z krajského kola zvítězil tým „Mackokládi“. Čtyři středoškoláci ze Dvora Králové uspěli s aplikací KompaZ. Jde o digitálního průvodce, který pomůže s rychlou a srozumitelnou orientací v životních i krizových situacích „krok za krokem“. Aplikace
… více »QGIS, svobodný desktopový GIS, byl vydán v nové hlavní verzi 4.0. Změny zahrnují několik nových analytických a editačních funkcí, rozšíření podpory 3D, více možností úprav uživatelského rozhraní či mnoho dalších zlepšení použitelnosti. Řada 3.44 má aktualizace plánovány do září.
Dan Blanchard vydal knihovnu pro Python chardet v nové verzi 7.0.0. S novou verzí byla knihovna přelicencována z LGPL na MIT. Souhlasili s tím všichni přispěvatelé? Dan Blanchard souhlasy vůbec neřešil. Zaúkoloval umělou inteligenci (Claude), aby knihovnu zcela přepsala a výslovně jí nařídil, aby nepoužila žádný LGPL kód. Dan Blanchard tvrdí, že se jedná o clean room design. Protistrana argumentuje, že umělá inteligence byla trénována
… více »Andy Nguyen si na svou herní konzoli PlayStation 5 (PS5) pomocí exploitu Byepervisor nainstaloval Linux (Ubuntu). V Linuxu si spustil Steam a PS5 tak proměnil v Steam Machine. Na PS5 může hrát hry, které jsou vydané pouze pro PC a jsou na Steamu [Tom's Hardware].
Správce sbírky fotografií digiKam byl vydán ve verzi 9.0.0. Jedná se o větší vydání provázené aktualizacemi knihoven. Mnoho dílčích změn se vedle oprav chyb týká uživatelského rozhraní, mj. editace metadat.
Byla vydána verze 2026 distribuce programu pro počítačovou sazbu TeX s názvem TeX Live (Wikipedie). Přehled novinek v oficiální dokumentaci.
Jihokorejská Národní daňová služba (NTS) zabavila kryptoměnu Pre-retogeum (PRTG) v hodnotě 5,6 milionu dolarů. Pochlubila se v tiskové zprávě, do které vložila fotografii zabavených USB flash disků s kryptoměnovými peněženkami spolu se souvisejícími ručně napsanými mnemotechnickými obnovovacími frázemi. Krátce na to byla kryptoměna v hodnotě 4,8 milionu dolarů odcizena. O několik hodin ale vrácena, jelikož PRTG je extrémně nelikvidní, s denním objemem obchodování kolem 332 dolarů a zalistováním na jediné burze, MEXC [Bitcoin.com].
Komunita kolem Linuxu From Scratch (LFS) vydala nové verze knih s návody na instalaci vlastního linuxového systému ze zdrojových kódů Linux From Scratch 13.0 a Beyond Linux From Scratch 13.0. Pouze se systemd.
Byla vydána nová stabilní major verze 25.12 linuxové distribuce primárně určené pro routery a vestavěné systémy OpenWrt (Wikipedie). Jedná se o nástupce předchozí major verze 24.10. Přehled novinek v poznámkách k vydání. Podporováno je více než 2200 zařízení.
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);
...
while(1) {
buf[i] = getdata();
if (buf[i] == '\n') {
break;
}
i++;
}
buf[i+1] = 0;
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.
while (1) {
i=0;
while(1) {
buf[i] = getdata();
if (buf[i] == '1') {
break;
}
i++;
}
if (!strcmp(buf,"l1")) {
print("equal");
}
}
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
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.
print? Nemá to být printf? Pak to půjde.
void print (char *string){
while (*string) {
while (!(UCSRA & (1 << UDRE)));
UDR = *string;
string++;
}
string = 0;
return;
}
, a pak začít používat std::string
vim ~/.emacs
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č?
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?
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
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?
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
)
#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ů)
zarizeni 7 zapinam zarizeni 2 zapinam zarizeni 3 zapinam zarizeni 4 zapinam zarizeni 5 zapinam zarizeni 6 zapinaPokud 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í.
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)
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ě.
print(PSTR("zapínám zarízení 1\n"));
Pokud se nepletu, tak už to tak bezvadně fungovat nebude.
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?
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š.
// 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
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
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.
(Nečetl jsem diskusi celou.) Ale možná by pomohla vlastní implementace strchr()
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.
Tiskni
Sdílej: