Stránka 1 z 1

Const char v C

Napsal: 30 bře 2011 00:03
od Zeppelin
Ahoj, potřeboval bych prosím poradit jestli někdo nevíte jak převést v C "unsigned char" na "const char" nebo jinak udělat abych místo "Hello World" mohl mít "unsigned char" získaný z jiné funkce. Děkuji moc.

const char msg[] = "Hello World!!!";

Re: Const char v C

Napsal: 30 bře 2011 17:17
od faraon
Mohl bys to zadání trochu víc rozvést? Nevím přesně odkud a kam chceš ten řetězec předávat. Co třeba něco takového?

Kód: Vybrat vše

#include <stdio.h>

/* vrací ukazatel na vybranou zprávu */
char* msg(int ktera)
      {
      static char msg0[]="Error :-(";
      static char msg1[]="Hello World!!!";
      static char msg2[]="Ahoj lidi.";

      switch (ktera)
             {
             case 1:  return msg1;
             case 2:  return msg2;
             default: return msg0;
             }
      }

/* vypíše řetězec od adresy */
void zobrazit(char* retezec)
     {
     printf("%s\n",retezec);
     }

/* hlavní program vybírá zprávy*/
int main(void)
    {
    char* zprava=NULL;

    zprava=msg(2);
    zobrazit(zprava);

    zobrazit(zprava=msg(1));

    zobrazit(msg(99));

    return 0;
    }

Re: Const char v C

Napsal: 30 bře 2011 17:56
od Zeppelin
Místo "Hello World!" číst číslo z příkazu níže který je součástí jiné funkce.

const char msg[] = "**Hello World!**";

decimal_second=(second[0]>>4)*10+(second[0] & 15);

Takže místo "Hello World!" bude hodnota "decimal_second"

Re: Const char v C

Napsal: 30 bře 2011 19:35
od faraon
Takže potřebuješ převést číslo na řetězec a vložit ho do místa v paměti kde je zapsaný ten původní Hello World?
Je to sice const, takže by z principu neměl jít měnit (překladač vyhodí error když to zkusíš), ale přes ukazatele se dá v Céčku zničit cokoliv, pokud máš do daného místa paměti právo zapisovat (takže není jisté že tohle bude fungovat vždy a všude, nebo se všemi kompilátory):

Kód: Vybrat vše

    const char msg[]="**Hello World!**";
    char* znak=NULL;

    printf("%s\n",msg);        /* zobrazí **Hello World!** */

    znak=msg+2;                /* nebo znak=&msg[2] */
    *znak='h';                 /* změní H na h */
    *(znak+6)='w';             /* změní W na w */
    printf("%s\n",msg);        /* zobrazí **hello world!** */

    sprintf(msg,("%d"),12345); /* zapíše nový řetězec */
    printf("%s\n",msg);        /* zobrazí 12345 */

Hlavně bacha ať ten nový řetězec není delší než původní, to bys tam mohl udělat pořádnou čihošť! I takhle tu na mě při kompilaci skáčou warningy že se v tom programu děje něco velmi nestandardního :blush:

Co má dělat ten výraz (second[0]>>4)*10+(second[0] & 15)? Cvičně jsem si to přepočítal a vycházejí mi divné věci:

0 = 0
1 = 1
2 = 2
3 = 3
4 = 4
5 = 5
6 = 6
7 = 7
8 = 8
9 = 9
10 = 10
11 = 11
12 = 12
13 = 13
14 = 14
15 = 15
16 = 10
17 = 11
18 = 12
19 = 13
20 = 14
21 = 15
22 = 16
23 = 17
24 = 18

P.S. Dovedu si celkem dobře představit že programový kód i s tím původním řetězcem bude natvrdo vypálený v nějaké ROM nebo zapsaný na zamčené flashce, takže v lepším případě se nezapíše nic, v horším nastane nějaká výjimka a pád programu.

Re: Const char v C

Napsal: 30 bře 2011 19:43
od Zeppelin
No měla by to být konverze z unsigned char na decimal. Já to nedělal takže nedokážu posoudit jestli je tam chyba nebo ne, ale je možný že jo. Víš jak jí opravit? A nevíte jak teda změnit aby to nebylo const char ale jenom char? Přikládám link na soubor kde je funkce

"void HD44780_print_string(HD44780 *me, const char c[]);"

a tam je definovaný ten "const char"


http://groups.google.com/group/hive76-d ... b.h?part=5

Re: Const char v C

Napsal: 30 bře 2011 21:39
od faraon
Jo takhle, ono je to v hlavičkovém souboru :-D
S tím const si vůbec nelam hlavu, to se tam dává proto, aby knihovní funkce nemohla omylem změnit řetezec který jí posíláš na zpracování. Ty ho v programu máš normálně a můžeš do něj zapisovat, ale kdyby se ho ta knihovna někde pokoušela měnit, tak kompilátor vyhodí chybu. Prostě na to const zapomeň, když tam necháš jen char msg[]="... tak to bude fungovat úplně stejně a bez warningů!

Zato ten vzorec mě pěkně potrápil, než jsem přišel na to co to vlastně znamená - ten čas je v second[0] uložený v kódu BCD (Binary Coded Decimal), v horních čtyřech bitech je vyšší desítková číslice, v dolních čtyřech nižší, takže například 59 sekund bude 0x59 (= 0101 1001). To načítáš z nějakého hodinového obvodu? Tohle se tím výpočtem převádí na desítkové číslo, a to pak příkazem sprintf vepíšeš do řetězce msg:

Kód: Vybrat vše

/* odeslání znaku na displej */
void HD44780_print_byte(unsigned char b)
{
 putchar(b);
}

/* vypisuje řetězec po znacích */
void HD44780_print_string(const char c[])
{
 while (*c)
   HD44780_print_byte(*c++);
}

/* převede číslo z BCD do desítkového */
int dec_sec(unsigned char second[])
    {
    int decimal_second=0;

    decimal_second=(second[0]>>4)*10+(second[0]&15);

    return decimal_second;
    }

/* zobrazí zprávy */
int main(void)
    {
    char msg[]="**Hello World!**";
    unsigned char second[]={0x59,0};

    HD44780_print_string(msg);
    putchar('\n');
   
    sprintf(msg,"%d",dec_sec(second));
    HD44780_print_string(msg);
    putchar('\n');

    return 0;
    }

Použil jsem pro výpis funkce z toho tvého odkazu, akorát jsem si je trošičku očesal o nepotřebné parametry, aby to šlo přeložit. Pro jaký to máš mikrokontrolér?

EDIT: Ještě mě napadlo, kdybys nechtěl použít nebo neměl k dispozici funkci sprintf, tak dvoumístné číslo převedeš do msg třeba takhle:

Kód: Vybrat vše

    int decimal_second;

    decimal_second=(second[0]>>4)*10+(second[0]&15);
    msg[0]=decimal_second/10+48;
    msg[1]=decimal_second%10+48;
    msg[2]='\0';
    HD44780_print_string(msg);
    putchar('\n');

Re: Const char v C

Napsal: 30 bře 2011 23:27
od Zeppelin
Děkuju, moc ale moc se v tom nevyznám, proč znova děláš ten přepočet? Já už mám hodnotu v desítkovém čísle. Přikládám raději můj kód tak jak ho potřebuji. K tomu je ten hlavičkový soubor a pak soubor který získává ten čas ale ten tu není potřeba. Jsem začátečník, učím se C od začátku podle knížky tak jak je to správné ale zároveň se učím programovat MCU (MSP430) a tak někdy potřebuju "přeskočit" na něco složitějšího čímž se toho také vždy spousty naučím. Čas úspěšně získávám z DS1307. Mám to odzkoušené ale teď to potřebuju zobrazovat :D

Kód: Vybrat vše

#include "HD44780Lib.h"

extern unsigned char decimal_second;
extern unsigned char second[],decimal_second,decimal_minute,decimal_hour,decimal_day,decimal_month,decimal_year;

HD44780 theHD44780;
const char msg[] = "**Hello World!**";

void SetTime (void)
{
  Clock_Initialization();
  vInitI2C_2();
  init_DS1307();
}

void setup (void)
{
  HD44780_init(&theHD44780,4,5,0,1,2,3);
  HD44780_begin(&theHD44780,16, 2);
  HD44780_print_string(&theHD44780, msg);
}

void loop(void)
{

}

Re: Const char v C

Napsal: 31 bře 2011 07:03
od skunkicz
používat ukazatel na const hodnoty a zapisovat na něj "natvrdo" je tedy ultraprasárna

Re: Const char v C

Napsal: 31 bře 2011 08:22
od Zeppelin
Já bych upravil ten hlavičkový soubor, myslím si že by to bylo nejlepší. Zkoušel jsem přepsat "const char" na "char" ale to nejde, stejně to háže že to musí být konstantní.

Re: Const char v C

Napsal: 31 bře 2011 17:44
od faraon
skunkicz píše:používat ukazatel na const hodnoty a zapisovat na něj "natvrdo" je tedy ultraprasárna

To fakt je, ale jak vidno, v Céčku ani konstanty nejsou v bezpečí ;-)


--- Doplnění předchozího příspěvku (31 Bře 2011 18:48) ---

Přepočet dělám proto, že nevím co všechno tam už máš, a navíc si radši všechno co zvládnu udělám sám, mám o to méně starostí s cizími knihovnami :-D
Zeppelin píše:Já bych upravil ten hlavičkový soubor, myslím si že by to bylo nejlepší. Zkoušel jsem přepsat "const char" na "char" ale to nejde, stejně to háže že to musí být konstantní.

Kde jsi přepsal to const, v deklaraci té proměnné? To by chybu dělat nemělo, tohle v Céčku normálně funguje:

Kód: Vybrat vše

char msg[16]="12345";

void zobraz(const char text[])
     {
     while (*text)
           putchar(*text++);
     }

int main(void)
    {
    zobraz(msg);
    putchar('\n');

    return 0;
    }

Vyzkoušej to nejdřív s jednoduchou zprávou, a kdyžtak sem postni co ti to vypíše za hlášení.
V té funkci loop() chceš průběžně vypisovat čas?
Koukal jsem že ten MSP430 je pořádně nabušená mašina, dokonce jeho instrukční kód je vzorovaný podle PDP-11, to bys k tomu mohl zkusit připojit elektrický psací stroj a zkusit rozjet nějaký starý UNIX :lookround:

Re: Const char v C  Vyřešeno

Napsal: 31 bře 2011 22:01
od Zeppelin
Tak už mi pomohl můj kamarád a je to vyřešené. Ještě to doladíme ale to co jsem potřeboval už mám. Přikládám to níže. Děkuji všem.

HD44780_init(&theHD44780,4,5,0,1,2,3);
HD44780_begin(&theHD44780,16, 2);
unsigned char i,c[5];
i=second[1]>>4;
c[0]= (0x30 | i);
c[2]= 0;
i=second[1]&0xf;
c[1]= (0x30 | i);
HD44780_print_string(&theHD44780, &c[0]); }