[C]Vlozeni cisel do charu :)

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod Hollowback 10. 6. 2008 09:18

Zdravim, v C prepisuju jeden program na sledovano netflow a potrebuju at uklada nejaka data do DB....
Chci vytvorit retezec, do ktereho vlozim promenne ruzneho typu...takze napr.: "INSERT INTO table VALUES(0,'dfas',7728828)" ....ale netusim jak to mam do toho dotazu dostat :)....v PHP se pro spojeni retezce s promennou pouziva "." myslel jsem, ze v C to je +, ale to mi vypise chybu "invalid operands to binary +" ......potrebuju jenom vedet jak to tam vlozit, nic vic :)
Athlon 64 X2 3600+, Gigabyte MA78GM-S2H, 2 GB AData DDR2 800MHz, 120GB Seagate 7200rpm, 250GB IBM Fedora 7
For Those About To Rock
WE SALUTE YOU!!!
Hollowback
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod pucmeloudek 10. 6. 2008 09:25

Uz jsem jednou odpovidal na podobnou otazku, ktera byla mezitim smazana.

Prace s retezci v cistem C je pomerne slozita a hlavne nebezpecna zalezitost - neznalost detailu muze vest k aplikaci VELMI nachylne k bezpecnostnim diram typu buffer overflow.
Durazne doporucuju nastudovat, vyborne je vse vysvetleno napr. v Ucebici jazyka C od Herouta. Tady na foru vam to nikdo tak pekne nevysvetli.

Ale abych nebyl uplne osklivej, na podobne ulohy je v C funkce sprintf.
pucmeloudek
Junior

Odeslat příspěvekod Hollowback 10. 6. 2008 09:48

diky moc..uz to funguje :)
Athlon 64 X2 3600+, Gigabyte MA78GM-S2H, 2 GB AData DDR2 800MHz, 120GB Seagate 7200rpm, 250GB IBM Fedora 7
For Those About To Rock
WE SALUTE YOU!!!
Hollowback
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod rb 10. 6. 2008 10:05

Ja by som zase odporucal pouzit triedu string z STL v C++. Je tam kopa metod na pracu s retazcami a navyse je to relativne bezpecne a malo nachylne na chyby typu buffer overflow. Ak ale nie je mozne pouzit C++, tak zostava iba opatrna praca s funkciou sprintf(), co je nieco ako printf(), akurat vysledok nejde na stdout, ale do tebou zvoleneho buffera. Na spajanie retazcov mas napr. strcat(), kde si opat treba davat pozor na velkost buffera. Na vytvorenie toho dotazu ti staci sprintf(), pouzijes to cca takto:

Kód: Vybrat vše
char  buffer[200]; // tu si velkost uprav podla potreby, pripadne si nejak inak zisti dlzku buduceho retazca a alokuj pamat pomocou malloc()
sprintf( buffer, "INSERT INTO table VALUES(%d, '%s', %d)", integer1, string, integer2); // integer1, string a integer2 su tie hodnoty, co tam chces dat


Pre zaujimavost v C++:
Kód: Vybrat vše
#include <string>
#include <sstream>
#include <iostream>
using namespace std;

int main(int argc, char ** argv)
{
   int integer1, integer2;
   integer1 = 0;
   integer2 = 7728828;
   string string1 = "dfas";
   stringstream buf;
   buf << "INSERT INTO table VALUES(" << integer1 << ",'" << string1 << "'," << integer2 << ")";
   string vysledok = buf.str();
   cout << vysledok << endl;
   return 0;
}


Edit: tak uz ti to ide...tak toto ignoruj.
Human knowledge belongs to the world;-)
rb
Junior
Uživatelský avatar

Odeslat příspěvekod pucmeloudek 10. 6. 2008 10:27

to rb: Samo ze trida string z C++ zvladne spoustu veci moc pekne, jenze podivej se na otazku - autor prispevku pise o C. Bez plusu.
Zadani je pro me svate :-)
pucmeloudek
Junior

Odeslat příspěvekod rb 10. 6. 2008 10:43

pucmeloudek píše:to rb: Samo ze trida string z C++ zvladne spoustu veci moc pekne, jenze podivej se na otazku - autor prispevku pise o C. Bez plusu.
Zadani je pro me svate :-)


Viem, ze pisal, ze to robi v C, ja som ponukol inu alternativu (C++), ktoru nemusi prijat, ak mu nevyhovuje. Pisal som aj alternativu, ze C++ nepouzije, tak snad nie je zlocin ponuknut aj riesenie, ktore sice vyzaduje zmenu kompilatoru, ale do buducnosti moze priniest viac vyhod ako nevyhod;-).
Human knowledge belongs to the world;-)
rb
Junior
Uživatelský avatar

Odeslat příspěvekod pucmeloudek 10. 6. 2008 12:05

Odpovim protiotazkou. A co ze je to vlastne na tom C++ zpusobu tak hezkeho, ze by se kvuli nemu mel menit programovaci jazyk? ten zapis obsahujici
<< ", '" <<
je preci priserne neprehlednej, jeden sql prikaz rozsekanej na spoustu malinkatech retezcu... A jeste k tomu ta priserna myslenka tvurcu knihovny C++ pouzit operator bitoveho posunu pro vystup... Vzdyt skoro neni poznat, ze je to jeden insert.

Vidim jednu jedinou vyhodu a tou je ona neexistence (velkeho) problemu s rezervaci potrebneho mista.
pucmeloudek
Junior

Odeslat příspěvekod rb 10. 6. 2008 13:29

No je to otazka zvyku. A prave vyhoda, ze sa netreba starat o alokaciu pamate je dost vyznamna. Velmi vela chyb v programoch je sposobenych nespravnou spravou pamate. Je pravda, ze v C sa da spravit program velky efektivny, ale to treba vediet...Inak mne osobne vystup/vstup do/z prudov pomocou << >> vyhovuje viac ako funkcie ala printf, kde navyse nemozes za behu skontrolovat skutocny typ parametrov, kdezto pri operator<<() a operator>>() ano. Ale tieto diskusie medzi zastancami C a zastancami C++ su ako medzi Windowsom a Linuxom, takze v tom uz nebudem radsej pokracovat;-).
Human knowledge belongs to the world;-)
rb
Junior
Uživatelský avatar

Odeslat příspěvekod mbing 10. 6. 2008 20:33

pucmeloudek píše:Odpovim protiotazkou. A co ze je to vlastne na tom C++ zpusobu tak hezkeho, ze by se kvuli nemu mel menit programovaci jazyk? ten zapis obsahujici
<< ", '" <<
je preci priserne neprehlednej, jeden sql prikaz rozsekanej na spoustu malinkatech retezcu... A jeste k tomu ta priserna myslenka tvurcu knihovny C++ pouzit operator bitoveho posunu pro vystup... Vzdyt skoro neni poznat, ze je to jeden insert.

Vidim jednu jedinou vyhodu a tou je ona neexistence (velkeho) problemu s rezervaci potrebneho mista.
Zase tu má někdo mindrák z C++.
V jazyce C při statické alokaci paměti má programátor tendenci odhadovat počet znaků, tedy zbytečně alokovat větší paměť (takové to "radši dáme char pole[1000]"), nebo musí dokonce počítat počet znaků v řetězci; při dynamické alokaci paměti používat malloc() a kontrolovat uvolnění paměti funkcí free(), což může být ve větších programech nekontrolovatelné. Za úniky paměti bych mlátil programátory MS Windows Mobile když musím mobil nesutále restartovat, abych měl paměť. Kontruktor třídy string sám alokuje a každá operace třídy string sama realokuje paměť o přesném počtu znaků řetězce.
Zápis pro stream je opravdu otázkou zvyku. Operátor << neznamená pouze bitový posun, ale může být přetížen pro jakoukoli operaci. Myšlenka tvůrců použít << pro stream je logická a to taková, že naznačuje směr proudu dat. V tomto zápisu navíc nemusíš čachrovat s formátováním začínajícím procentem, typ si zjistí sám. Navíc má lehce použitelný manipulátor flush pro vyprázdnění vyrovnávací paměti. Další výhody mě nenapadají, ale jazyk C++ má ve svém názvu inkrementaci jako přidaná hodnota jazyka C, tak proč si nepřiznat, že je lepší. ;)
Nemám problémy s alkoholem, mám problémy bez něj.
mbing
VIP uživatel
Uživatelský avatar

Odeslat příspěvekod pucmeloudek 11. 6. 2008 11:01

Ted jsi uhodil hrebicek na hlavicku. "ale může být přetížen pro jakoukoli operaci". Potes panbuh, kdyz ho nekdo pretizi jeste pro neco jineho, to uz pak opravdu na pest, takovej program cist.
Skladani retezcu z jednotlivej kousku pomoci operatoru je dost neprijemne. U sql-prikazu se to zkousnout jeste da, ale kdyz nejakej "chytrak" takhle sklada i programove hlasky - to je potom chudak prekladatel, kterej ty kousicky musi samostatne prekladat.
pucmeloudek
Junior

Odeslat příspěvekod pucmeloudek 11. 6. 2008 12:08

A vlastne jeste par poznamecek:
1.
Co je tak tragickeho na tom, ze pro podobne ucely naalokuju zbytecne moc velkou promennou? Promenne pro podobne ucely se obycejne alokuji na zasobniku a nevidim valneho rozdilu mezi tim, jestli zacatek funkce po prelozeni zacina necim jako add sp, 200 nebo add sp, 1000. Do zasobniku se (pro rejpaly, krome rekurze) vejde tech 1000 bajtu snadno.

2.
Jestli nekdo neni schopnej uhlidat sparovani malloc a free v podobne trivialnich pripadech (zivotnost objektu nutnych pro naformatovani retezce je obvykle omezena na jednu funkci - viz tenhle s sql: naalokuju, naformatuju, pouziju, uvolnim, konec),
tak je u me lajdak. Staci poctive odsazovat a chybejici free prasti do oci i bez nastroju pro kontrolu uniku pameti.

3. nejak nechapu souvislost manipulatoru flush a formatovani stringu, ale stejne: mezi komplikovanosti manipulatoru flush a volanim funkce flush nevidim valneho rozdilu.

Osobne mi prijde C-ckova myslenka s formatovacim retezcem jako NEJPREHLEDNEJSI zpusob tvorby retezcu z dat, ktery byl doveden k dokonalosti v .Netu a jeho String.Format.

// edit: par preklepu a stylistickych prisernosti opraveno ;-]
pucmeloudek
Junior

Odeslat příspěvekod suk 12. 6. 2008 09:31

pucmeloudek:

pretezovani vidim jako hodne dobrej nastroj pri objektovym programovani. V .NETu ktery na konci vychvalujes (ja ho mam taky rad a pouzivam, neboj) maj defaultni tridy takovejch prepsanejch operatoru.

1. a ted velkej program, kde tech 1000 bajtu alokujes tisickrat - mas to skoro jeden MB... kdyz to takhle na nejakym mobilnim zarizeni co ma 64MB RAM udela nekolik aplikaci, nakonec dojdes k restartu jak pise mbing

2. u vetrisho softiku muzes neco alokovat na zacatku a chtit freeovat nekde pozdeji - muzes na to zapomenout, ted uz ti indent nepoumuze

String.Format, pripadne sprintf je dobrej napad. A sprintf se pokud vim da pouzit i v C++ ne?
Pokud nesouhlasíte s mým názorem, popřemýšlejte sami nad sebou. Opravdu si myslíte, že já bych se mohl mýlit?
----
You are an inspiration for a birth control...
suk
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod Nargon 12. 6. 2008 10:38

Veskere funkce a moznost z jazyku C, funguji v C++. Takze osobne doporucuji pouzivat C++ a treba celej kod psat v C, fungovat to bude. A kdyz bude nejakej problem s jako ted, tak klidne pouzit << z c++
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod pucmeloudek 12. 6. 2008 11:58

ad pretezovani - pretezovat operatory pro jine operace nez jsou pouzity v jazyku samotnem mi jako dobry napad neprijde. presne naopak. pretizit onen diskutovany operator "<<" tak, ze mi do proudu vypise treba stav objektu, uz tak spatny napad neni. Operator pro explicitni pretypovani bych pretezoval taky rad, kdybych c++ pouzival :-)

1. program, kde se alokuje NAJEDNOU 1000 x 1000 bajtu PRO TVORBU RETEZCE (!) (zduraznuji pro tvorbu retezce, jeste jednou!) neexistuje. retezec vytvorim, pouziju a uvolnim. mezi vytvorenim bufferu pro retezec a jeho uvolnenim se dalsich tisic rekurzivne tvorit nikdy nebude. Mozna 1, 2, 3, vic tezko. takze to opravdu problem neni.

2. jisteze jsou pripady, kdy neco alokuju na zacatku a uvolnim v jinym souboru za mnoho hodin behu programu. Na to potom jsou specializovane nastroje, ktere podobne uniky pameti odhali (treba komercni aqtime to zvlada se vsi paradou.) Opakuji znovu, to se ale nemuze stat pri vytvareni bufferu pro formatovani retezce s sql, ktery bude hned pouzit. Tam je doba zivota dana naprosto jasne, tudiz nebezpeci uniku pameti je pramale.

sprintf se v c++ pouzit urcite da :-) ovsem ten stejny zdrojak prelozeny prekladacem c a c++ ma, ehm, trochu jine rozmery.
Naposledy upravil pucmeloudek dne 12. 6. 2008 12:10, celkově upraveno 1
pucmeloudek
Junior

Odeslat příspěvekod pucmeloudek 12. 6. 2008 11:59

ad nargon
veskere ne :-) treba se zapisem funkci podle K&R si C++ prekladac neporadi :-)
pucmeloudek
Junior


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků