Pár dotazů – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Pár dotazů – C / C++ – Fórum – Programujte.comPár dotazů – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
oxidián0
Grafoman
6. 3. 2015   #1
-
0
-

Odstraňuju teď upozornění v celém programu tak možná ještě budu mít nějaké další dotazy, ale aktuálně mě zajímá jestli to nedělám moc složitě:

char first_[25],second_[25],
prefix_[12],suffix_[12],mid_[12],
ext_[6],
regext_[6];

char * first;
char * second;
char * prefix;
char * suffix;
char * mid;
char * ext;
char * regext;

first=first_; second=second_;
prefix=prefix_; suffix=suffix_;
mid = mid_; ext = ext_; regext = regext_;
first[0]='\0'; second[0]='\0';
prefix[0]='\0'; suffix[0]='\0';
mid[0]='\0'; ext[0]='\0';
regext[0]='\0';

 

Zkoušel jsem napsat rovnou char*prefix[24]; ale to mi vytvořilo něco úplně jiného než char*. Je to funkce na parsování tak jsem se rozhodl vyhnout se dynamickému přiřazování paměti

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
6. 3. 2015   #2
-
0
-

Tohle tak snadno neobejdes. Musis mit pole znaku a pointer na jejich zacatek.

char *prefix[24] znamena pole 24 pointeru

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
PiranhaGreg0
Stálý člen
6. 3. 2015   #3
-
0
-

Já nějak nechápu, proč to neuděláš takhle... 

char first[25] = { 0 };
char second[25] = { 0 };
char prefix[12] = { 0 };
char suffix[12] = { 0 };
char mid[12] = { 0 };
char ext[6] = { 0 };
char regext[6] = { 0 };
Nahlásit jako SPAM
IP: 109.81.210.–
oxidián0
Grafoman
6. 3. 2015   #4
-
0
-

Tak asi proto že nevím že to tak jde, proto se ptám. Díky.

A potřeboval bych poradit s touto funkcí, kterou jsem upravil z strncpy:

char * str1cpy(char *s1, const char *s2, uint16_t n)
{
    char *s = s1;
    s2+=n;
    if ( *s2 != '\0')
      *s++ = *s2;
    *s++ = '\0';
    return s1;
}


má zkopírovat jeden znak z jednoho řetězce do druhého. Rozhodující o pozici kterou chci zkopírovat je n.

Předpokládaná aplikace:

if ( arg[n] != '{' )
     str1cpy(prefix,arg,n);


má do prefixu zkopírovat znaky které jsou před závorkou.

Problém tedy je v tom, že na řádku 6 jehož roli nechápu úplně přesně, se mi vždy přepíše první znak místo znaku n-tého.

Zkoušel jsem to opravit na

if ( *s2 != '\0') {
      *s +=n; 
	  s=*s2;
	  }

ale výsledkem je s adress out of bounds

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
6. 3. 2015   #5
-
0
-

mozna dej radeji retezec pred a retezec po (co chces a co to dela) - bude to jednodussi na pochopeni co ze to vlastne chces

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
PiranhaGreg0
Stálý člen
6. 3. 2015   #6
-
0
-

Taky úplně nechápu co chceš. Jestli zkopírovat prvních n znaků, tak to může vypadat nějak takto 

char * arg = "Nejaky text se { zvorkou.";
char prefix[256];
int i;

for(i = 0; arg[i] != '{'; i++)
	prefix[i] = arg[i];

prefix[i] = '\0';
Nahlásit jako SPAM
IP: 109.81.210.–
oxidián0
Grafoman
6. 3. 2015   #7
-
0
-

Mám smyčku ve které volám

char * arg="123_{1}_{2}.jpg";

char prefix[12] = { 0 };

// získej prefix

str1cpy(prefix,arg,0); // prefix = "1"

str1cpy(prefix,arg,1); // prefix = "12"

str1cpy(prefix,arg,2); // prefix = "123"

str1cpy(prefix,arg,3); // prefix = "123_"

Po jednom znaku to má kopírovat ze stringu arg na konec prefix. n říká který znak chci zkopírovat.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
6. 3. 2015   #8
-
0
-

vypada docela neefektivne... proc nemit ziskani prefixu, kdy bude kontrolovat nejen '\0' ale i '{' jakozto terminal?

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
PiranhaGreg0
Stálý člen
6. 3. 2015   #9
-
0
-

Tak asi takhle, ale je to šíleně neefektivní... 

void strlcpy(char * prefix, char * arg, int n) {
	int l = strlen(prefix); 
	prefix[l++] = arg[n];
	prefix[l] = '\0';
}
Nahlásit jako SPAM
IP: 109.81.210.–
oxidián0
Grafoman
6. 3. 2015   #10
-
0
-

A to nejde udělat bez toho strlen? Ta moje funkce předpokládá, že s1 je prázdný řetězec, tzn. n by teoreticky mohlo udávat pozici na uložení.

Zkoušel jsem ještě toto:

    s1+=n; s2+=n;
    if ( *s2 != '\0')
	  *s1 = *s2;
	s1[n+1] = '\0';

ale výsledek je stejný. Nejdříve se do s1 nastaví jeden znak, při dalším zavolání se ale opět přepíše. Já chci posunout ten ukazatel o n znaků a zkopírovat tam to na co ukazuje s2

Nahlásit jako SPAM
IP: 78.45.199.–
PiranhaGreg0
Stálý člen
6. 3. 2015   #11
-
0
-

Tak jestli ti nevadí posouvání s tím stringem prefix, tak to lze zařídit takhle 

void strlcpy(char ** prefix, char * arg, int n) {
	**prefix = arg[n];
	*(*prefix)++ = '\0';
}

ale zbytečně si to komplikuješ... Musíš si pak totiž někde udělat zálohu toho původního ukazatele. Při volání té funkce pak bude první argument ve tvaru &prefix.

Nahlásit jako SPAM
IP: 109.81.210.–
PiranhaGreg0
Stálý člen
6. 3. 2015   #12
-
0
-

Podle mě si to všechno moc komplikuješ. Kdyby jsi napsal (jak doporučil KIIV) jaký jsou vstupy a jaký očekávaný výstupy, tak to tady nemusíme řešit a napíšu ti rovnou správnou funkci...

Nahlásit jako SPAM
IP: 109.81.210.–
oxidián0
Grafoman
6. 3. 2015   #13
-
0
-

Vždyť jsem to napsal v příspěvku 7.

Už jsem na to přišel:

char * str1cpy(char *s1, const char *s2, uint16_t n)
{
    s1+=n; s2+=n;
    if ( *s2 != '\0')
	  *s1 = *s2;
	s1[n+1] = '\0';
    return s1-n;
}


Problém byl v tom že to nebylo vidět a vracelo to nesprávnou adresu, takže aby to bylo vidět po editaci je třeba dát s1-n. Tvůj kód je kratší ale zase není tak přehledný a vyžaduje char ** jako vstup já mám vstup char*

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
6. 3. 2015   #14
-
0
-

#8 KIIV
Já chtěl původně udělat to co v c++ lze udělat pomocí mystr += someChar , čili jen přičíst jeden znak. A to v Céčku nejde. Funkci na to jsem si napsal. Neefektivní to možná je, ale je to v situaci, kdy parsuji jeden krátký argument něco ve stylu:  -r prefix_{x:číslo}_{y:číslo}.jpg původně jsem to psal v C++ a tam se dal přičíst ten znak, takže celé to cykluju po jednotlivých znacích v jedné velké smyčce. Jasně, šlo by to udělat i jinak jako po jednotlivých částech, ale funkce už je napsaná a tady ohledně toho přefixu pravděpodobně jde jen o tři znaky které chci takto načíst do prefixu, takže žádná tragédie.

Jediným problémem této funkce je to, že přepíše ten původní cílový string. Teď nevím jestli je to špatně nebo ne, protože musím ještě zkontrolovat jak tu funkci používám dál a jestli mi na konci celé funkce na parsování regexu vyleze co jsem chtěl.

Edit:

Jo tak problém to je. Vlastně původní záměr není splněn. Protože když chci získat to slovo uvnitř závorky tak toto nefunguje. Tam je odlišná pozice n. Jak říkám původně jsem chtěl udělat funkci na mystr += someChar, takže to budu muset přepsat nebo nějak obejít.

Když mám ten prefix hotový mám další kód:

for (n++; arg[n] != '}' || n>=length-1; n++)
    str1cpy(first,arg,n); // first += arg[n];

zas je ale problém v tom že first není char *

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
6. 3. 2015   #15
-
0
-

no ja navrhoval neco jako:

while (*in != '\0' && *in != '{') *out++ = *in++;
*out = '\0';
Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
PiranhaGreg0
Stálý člen
6. 3. 2015   #16
-
0
-

Já si zas myslím, že na tyhle věci je ideální scanf. Zkus ti tohle demíčko pro různý vstupy, jestli ti to sedne... 

char * test = "prefix_{x:12}_{y:8}.jpg";
char prefix[12];
int x, y;

if (sscanf(test, "%11[^_]_{x:%d}_{y:%d}.jpg", prefix, &x, &y) != 3)
	printf("fail\n");
else
	printf("%s_{x:%d}_{y:%d}.jpg\n", prefix, x, y);
Nahlásit jako SPAM
IP: 109.81.210.–
oxidián0
Grafoman
6. 3. 2015   #17
-
0
-

#17 PiranhaGreg
No jo, když ono je to komplikovanější. V té mé funkci jsou podmínky, že třeba x nebo y nemusí být zadané a místo toho tam bude jen pomlčka. Já bych raději rozjel nejdříve tu funkci od KIIV.

Copy/paste z mých poznámek:

-r _{...}_{...}_ is translated as -r _{x:..}_{y:...}_

other forms:
-r _{x:-}_{y:...}_
-r _{x:...}_{y:-}_
-r _{y:..}_{x:...}_
-r _{y:-}_{x:...}_
-r _{y:...}_{x:-}_

V některých případech tam číslo není zadané, ale existuje číslo v druhé závorce. Prostě je to komplikovanější funkce.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
6. 3. 2015   #18
-
0
-

#15 KIIV
Díky moc, už to jede

char * strcpyUntilChar(char *out, char *in, char ch){
while (*in != '\0' && *in != ch) *out++ = *in++;
    *out = '\0';
return out;
}
Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
7. 3. 2015   #19
-
0
-

#3 PiranhaGreg
No jo ale jak dořešit to, že ty proměnné nejsou char *? 



    char first[25] = { 0 };
    char second[25] = { 0 };
    char prefix[12] = { 0 };
    char suffix[12] = { 0 };
    char mid[12] = { 0 };
    char ext[6] = { 0 };
    char regext[6] = { 0 };

    x=-1;y=-1;
    if (prefixProc){
        strcpyUntilChar(prefix, arg, '{');
        length = strlen(prefix);
        first+=(length-1);
        strcpyUntilChar(first, arg, '}');
        }



first+=(length-1) dává chybu

error: invalid operands to binary + (have 'char[25]' and 'int')|

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
7. 3. 2015   #20
-
0
-

Zdá se že to mám vyřešeno:

http://paste.ofcode.org/7zUDnbvWSLFCMij3AhCqWY

Výrazně se to zjednodušilo. Až na tu deklaraci char * na začátku. zatím to funguje, zítra ještě ověřím jestli to bude fungovat když odstraním prefix (nepovinný)

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #21
-
+1
-
Zajímavé

#20 oxidián
Neni nad prehlednost:

#include <stdio.h>

const char * strcpyUntilChar(char *out, const char *in, char ch)
{
    while (*in != '\0' && *in != ch) *out++ = *in++;
    *out = '\0';
    return in;
}

enum polozky {
  FIRST,
  SECOND,
  PREFIX,
  SUFFIX,
  MID,
  EXT,
  REGEXT,
  LAST
};

int main()
{
    const char * arg = "123_{1}_{2}.jpg";
    char arr[LAST][50] = {0};
    
    arg = strcpyUntilChar(arr[PREFIX], arg, '{'); if (*arg != '\0') ++arg;
    arg = strcpyUntilChar(arr[FIRST], arg, '}');  if (*arg != '\0') ++arg;
    arg = strcpyUntilChar(arr[MID], arg, '{');    if (*arg != '\0') ++arg;
    arg = strcpyUntilChar(arr[SECOND], arg, '}'); if (*arg != '\0') ++arg;
    arg = strcpyUntilChar(arr[EXT], arg, '\0');

    printf("'%s' '%s' '%s' '%s' '%s'\n",arr[PREFIX],arr[FIRST],arr[MID],arr[SECOND],arr[EXT]);
}
Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #22
-
+1
-
Zajímavé

pripadne se da pouzit strtok_r (reentrant verze, protoze chces asi pouzivat vic vlaken a strtok neni thread safe)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #23
-
0
-

Oh sh*t to díky za upozornění! Zavedl jsem si funkci strTok, která nepoužívá statické proměnné takže to mám vyřešeno. Pozn. k parsování argumentů ale více vláken používat nebudu.

Dotaz:

Jak tam řešíš typ char*? Vidím tam jen typ enum. Já už začal uvažovat o tom, že ty zásobníky co jsem zavedl jsou zbytečné a že by mi stačil jen jeden.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #24
-
0
-

Enum je tam jen pro "citelnejsi" index do toho pole retezcu o delce 50.

Precijen  arr[0] je trosku min citelne nez  arr[FIRST]. Kdyz uz se usetrily zbytecny promenny.

No a kdyz predas te funkci arr[FIRST], tak je to primo zamenitelne s  char *.

A ano, ten buffer by stacil klidne jeden - zalezi na tom, co s tim dal delas. Nebo jen pole pointeru a ty oddelovace prepisovat '\0' (jen v pripade, ze uz ten puvodni retezec nepotrebujes jeste v celku)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #25
-
0
-

Když přehlednější tak přehlednější, tak jsem to udělal takto

    char * first;
    char * second;
    char * prefix;
    char * suffix;
    char * mid;
    char * ext;
    char * regext;


    // const char * arg = "123_{1}_{2}.jpg";
    char arr[LAST][50] = {0};

    arg = strcpyTillCharIn(arr[PREFIX], arg, '{'); prefix = arr[PREFIX];
    if (*arg != '\0') arg++;
    arg = strcpyTillCharIn(arr[FIRST], arg, '}'); first = arr[FIRST];
    if (*arg != '\0') arg++;
    arg = strcpyTillCharIn(arr[MID], arg, '{'); mid = arr[MID];
    if (*arg != '\0') ++arg;
    arg = strcpyTillCharIn(arr[SECOND], arg, '}'); second = arr[SECOND];
    if (*arg != '\0') ++arg;
    arg = strcpyTillCharIn(arr[REGEXT], arg, '\0'); regext = arr[REGEXT];

    printf("'%s' '%s' '%s' '%s' '%s'\n",prefix,first,mid,second,regext);


Dík za pomoc. A ještě jsem si uvědomil že vlastně budu muset parsovat názvy souborů až budu procházet adresář a to bude multivláknově. Takže se vyhnu tomu strtok. Tam by se dal použít ten scanf.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #26
-
0
-

#25 oxidián
strtok_r muzes pouzit. Je to verze, co se s vice vlaknama pouzit da. Jen strtok neni bezpecny.

Mozna sem mel trosku upravit tu puvodni funkci na:

const char * strcpyUntilChar(char *out, const char *in, char ch)
{
    while (*in != '\0' && *in != ch) *out++ = *in++;
    *out = '\0';
    return *in!='\0' ? in+1 : in;
}


cimz by se pointer posunul za ch, ale pokud by uz byl ten ukoncovaci znak, tak by se neposouval

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #27
-
0
-

a kdyz furt trvas na tech pointerech tam (ikdyz jsou pravdepodobne zbytecny), tak:

    char arr[7][50] = {0};
    char * first  = arr[0];
    char * second = arr[1];
    char * prefix = arr[2];
    char * suffix = arr[3];
    char * mid    = arr[4];
    char * ext    = arr[5];
    char * regext = arr[6];

    arg = strcpyTillCharIn(prefix, arg, '{'); // za predpokladu upravy z predchoziho prispevku
    arg = strcpyTillCharIn(first, arg, '}');
    arg = strcpyTillCharIn(mid, arg, '{');
    arg = strcpyTillCharIn(second, arg, '}');
    arg = strcpyTillCharIn(regext, arg, '\0');

    printf("'%s' '%s' '%s' '%s' '%s'\n",prefix,first,mid,second,regext);
Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #28
-
0
-

Prokouklo to, ale já už nesleduju jak ta tvá funkce funguje. U té mé byl problém že pointer musel být ve větším rozsahu. Naříklad prefix pravděpodobně bude mít jen 3 znaky, koncovka regext asi jen max. 6 znaků  např. *.jpeg, mid je jenom spojka, tak asi jeden znak, takže nevím jestli je nutné nastavovat všem stejnou délku, ale ono je to tak vlastně jednodušší.

Tak já bych tam nechal

    char arr[LAST][50] = {0};
    char * first=arr[FIRST];
    char * second=arr[SECOND];
    char * prefix=arr[PREFIX];
    char * suffix=arr[SUFFIX];
    char * mid=arr[MID];
    char * ext=arr[EXT];
    char * regext=arr[REGEXT];

Ale ideální by bylo kdyby šlo nadefinovat velikost pro ty jednotlivé elementy v enum

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #29
-
+1
-
Zajímavé

spis ukaz, na co to potrebujes, ja stale trvam na tom, ze je to naprosta zbytecnost.

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #30
-
0
-

Zbytečnost to sice je, ale pěkná.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
7. 3. 2015   #31
-
0
-

Opět mi kompilátor hází několik chyb/upozornění:

char arr[LAST][50] = {0};

warning: missing braces around initializer [-Wmissing-braces]|

near initialization for 'arr[0]') [-Wmissing-braces]|

arg = strcpyTillCharIn(prefix, arg, '{');

warning: assignment discards 'const' qualifier from pointer target type [enabled by default]|

to je něco podobného jako jsme řešili v minulém vlákně.

Nahlásit jako SPAM
IP: 78.45.199.–
vitamin+8
Grafoman
7. 3. 2015   #32
-
0
-

#31 oxidián
skus: 

char arr[LAST][50] = {{0}};
Nahlásit jako SPAM
IP: 95.105.229.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #33
-
0
-

mozna arg nemas jako const char *  ale jen jako  char * ... pak se pri prirazeni zmeni z const na neconst a tim padem je "odstraneni kvalifikatoru const a neni to const"

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #34
-
0
-

Teď jsem našel další chybu (funkce podobná jako v minulém vlákně - actions_strings je makro):

char * getAction_str(int a){
    return actions_strings[a];}



warning: excess elements in array initializer

get_fnc.c|10|warning: (near initialization for '(anonymous)')

warning: return discards 'const' qualifier from pointer target type

#define actions_strings (const char*[6]){"threshold", "levels" }
Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
7. 3. 2015   #35
-
0
-

#33 KIIV
Který argument in nebo out? Vrací const, out není const a in je const

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
7. 3. 2015   #36
-
0
-

Víš co u té tvé funkce nechápu? Proč na konci vracíš in+1 a ne *in+1 nebo *in?

/* Tam kde je *var se pracuje se stringem jak kdyby na
    původní úrovni mimo funkci */
char * strcpyTillCharIn(char *out, const char *in, char ch)
{
    /* Posouvá ukazatele tak dlouho dokud *in se
        nerovná char nebo konec řetězce */
    while (*in != '\0' && *in != ch) *out++ = *in++;
    *out = '\0'; // ukončovací znak se zapíše jen do výstupního stringu

    /* na konci stringu, pokud nejde o konec řetězce,
    musí posunout ukazatel tak, aby ve výsledku nebylo
    hledané písmeno */
    return *in!='\0' ? in+1 : in;
}
Nahlásit jako SPAM
IP: 78.45.199.–
7. 3. 2015   #37
-
+1
-
Zajímavé

Protože vrací ukazatel a ne hodnotu na kterou ukazuje.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #38
-
0
-

abys nedelal pokazdy strlen a nepocital delku... vracim pointer na za znak, ktery se zpracoval naposledy, nebo na '\0' (tam je zadouci nepripocitavat 1, protoze by tam uz dalsi nula byt taky nemusela)

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #39
-
0
-

Jo, dobrý tu funkci už mám komplet hotovou a už to chápu. Teď zas dělám něco jiného. Zkouším načíst binární soubor, načetl jsem hlavičku o délce 50 znaků do bufferu. Znaky v něm jsou zapsány zleva doprava (takže big endian). Mám v PC dvě funkce na převod:

#define UINT16_SWAP_LE_BE_CONSTANT(val)		\
  ((uint16_t)					\
   (						\
    (uint16_t) ((uint16_t) (val) >> 8) |	\
    (uint16_t) ((uint16_t) (val) << 8)))

#define UINT32_SWAP_LE_BE_CONSTANT(val)			  \
  ((uint32_t)						  \
   (							  \
    (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \
    (((uint32_t) (val) & (uint32_t) 0x0000ff00U) <<  8) | \
    (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >>  8) | \
    (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))

Ale nevím jestli je to to co potřebuju. Když chci převést první čtyři znaky na uint32_t co mám udělat? Musím nejdříve ty 4 znaky nakopírovat do nějakého stringu a ten pak převést pomocí val=atoi(str)? A pak
UINT32_SWAP_LE_BE_CONSTANT(val)?
 

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
7. 3. 2015   #40
-
0
-

A když volám

    read4bytes(buffer, &h.magicno1);
    h.magicno1 = UINT32_SWAP_LE_BE_CONSTANT(h.magicno1);

Edit:

Myslím že jsem to vyřešil. Převedl jsem to a doufám že to mám správně:

uint16_t UINT16_SWAP_LE_BE_CONSTANT(uint16_t val){
    return (
    (uint16_t) ((uint16_t) (val) >> 8) |
    (uint16_t) ((uint16_t) (val) << 8)
    );
}

uint32_t UINT32_SWAP_LE_BE_CONSTANT(uint32_t val)
  {
  return ((uint32_t)
   (
    (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) |
    (((uint32_t) (val) & (uint32_t) 0x0000ff00U) <<  8) |
    (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >>  8) |
    (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)
    )
  );
  }


tak dostávám hlášku

undefined reference to `UINT32_SWAP_LE_BE_CONSTANT'|

edit2:

A zjistil jsem že tu funkci nepotřebuju, že mi to ta funkce

void read4bytes(unsigned char * pSourceStr, uint32_t* item)
{
  memcpy(item,pSourceStr,4);
  pSourceStr+=4;
}

sama převede na správné číslo. Takže teď nevím, jestli ten zdroj je little endian nebo big endian, když je zapsaný zleva doprava? To číslo co jsem dostal je 428999169 a po převodu na HEX je 19 92 02 01 čteno zprava to odpovídá tomu co je v souboru čtené zleva. Tak nevím jestli mám výsledek v little endian nebo v big endian?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #41
-
0
-

Kazdopadne lepsi by byla ta hlaska cela. Pokazdy to orezes o "nedulezity" informace, ktery jsou ve skutecnosti esencialni.

Muze to byt treba tim, ze sice mas deklaraci v headeru, ale definice jsou schovany v nejakem *.c souboru, ktery nelinkujes k vysledku.

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #42
-
0
-

#41 KIIV
Definice tam je, ale deklarace ne. Já měl za to že když je tam #define tak že to deklarovat nemusím. Ale nevím jaká je výhoda define, dal jsem to normálně bez define ale asi to nepotřebuju. Viz edit2: Když v souboru je číslo HEX čtené zleva doprava a funkce mi vrátí číslo HEX čtené zprava doleva, je ten výsledek v little endian nebo big endian? Zdroj byl myslím BE ale moje PC x86 pracuje v LE tedy zprava doleva, že?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #43
-
0
-

u funkci je deklarace:

int funkce(int, char, char*);

a definice:

int funkce(int a, char c, char* str) {

...

}

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #44
-
0
-

no tak tam bylo to makro tak nevím proč to dávalo chybovou hlášku

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
7. 3. 2015   #45
-
0
-

A vypis hexa hodnot na obrazovku ti to vypise v prirozeny forme - tj. tak jak se zobrazuji cisla v pozicnich soustavach.

Jinak procesory x86 prezentuji cisla vzdy v little endianu. Ale jsou dalsi, co pouzivaji big endian. Pak dalsi, co si muzou vybrat.

Kazdopadne nejnizssi adresa bajtu v pameti ma v little endianu nejmensi vyznam. Bajt se zmeni o 1 a cislo se zmeni taky o 1. U big endianu zmenis byte na nejnizssi adrese, a to cislo se zmeni o 2^8 nebo 2^24

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
7. 3. 2015   #46
-
0
-

V té hlavičce jsou uint32_t datum:


E8 C7 C6 01
High = 29804520
=> February 27, 2007

Co musím udělat abych z toho integru dostal tohle datum?

Zkouším toto:

    char date1[25],date2[25];
    struct tm* tm_info;
    tm_info = localtime(&h.dwLowDateTime); // in: time_t
    strftime(date1, 25, "%Y:%m:%d%H:%M:%S", tm_info);
    tm_info = localtime(&h.dwHighDateTime); // in: time_t
    strftime(date2, 25, "%Y:%m:%d%H:%M:%S", tm_info);


a to mi krachuje.

tm_info   (struct tm *) 0x0

nemá nastaven pointer

A toto mi taky krachne:

strftime(date1, 25, "%Y:%m:%d%H:%M:%S", localtime(&h.dwLowDateTime));

strftime(date2, 25, "%Y:%m:%d%H:%M:%S", localtime(&h.dwHighDateTime));

A ještě bych potřeboval převést číslo uint_32 na stupně ve formátu float. Jak na to?

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
8. 3. 2015   #47
-
0
-

Ale mám vůbec problém jak načíst ty údaje z binárního souboru. Potřebuji načíst datum a souřadnice. Souřadnice jsou uint32_t a datum taky.

Vytvořil jsem si strukturu na ty souřadnice:

typedef struct LONLAT_ {
    uint32_t minLat;
    uint32_t maxLat;
    uint32_t minLon;
    uint32_t maxLon;
} LONLAT_t;


A uvnitř hlavní struktury mám toto:

typedef struct HEADER_ {

    uint32_t dwLowDateTime; // uint32_t
    uint32_t dwHighDateTime; // uint32_t
//    time_t dwLowDateTime; // uint32_t
//    time_t dwHighDateTime; // uint32_t
    uint32_t * coords[4]; // Coordinates:

}

} HEADER_t;

Pak si vytvořím pole kam chci ukládat ty hodnoty a taky mám funkci na čtení 4 bytů, která mi má nastavit tu hodnotu:

LONLAT_t geoloc[4];

read4bytes(&buffer, &h.dwLowDateTime);
read4bytes(&buffer, &h.dwHighDateTime);
read4bytes(&buffer, &h.coords);


Ale na posledním řádku mám problém:

warning: passing argument 2 of 'read4bytes' from incompatible pointer type

void read4bytes(unsigned char ** pSourceStr, uint32_t* item);

    expected 'uint32_t *' but argument is of type 'uint32_t * (*)[4]'|

takže potřebuju poradit jak načíst ty hodnoty a převést je správně

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
8. 3. 2015   #48
-
0
-

#47 oxidián
mas tam:
uint32_t * coords[4]; // Coordinates:
coz je ponekud rozdil od  uint32_t  ktery predavas naprosto presne stejne.

A ted dotaz, proc zrovna 4 pointery na uint32_t? V souboru to jako pointer 100% nebude.

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
8. 3. 2015   #49
-
0
-

Už jsem si toho všiml a provedl jsem nějaké opravy, ale ještě tam mám problém pointerem.

LONLAT_t * GetBoundingCoordinates(uint32_t boundingValue, LONLAT_t * lonlat );
read4bytes(&buffer, &h.coords[0]);

warning: passing argument 2 of 'read4bytes' from incompatible pointer type [enabled by default]|

note: expected 'uint32_t *' but argument is of type 'uint32_t **'|

Potřebuju dát tam ten pointer na LONLAT_t? Chci přece updatovat proměnnou...

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
8. 3. 2015   #50
-
0
-

Proc tam potom nemas toto:

typedef struct LONLAT_ {
    uint32_t minLat;
    uint32_t maxLat;
    uint32_t minLon;
    uint32_t maxLon;
} LONLAT_t;

typedef struct HEADER_ {
    uint32_t dwLowDateTime; // uint32_t
    uint32_t dwHighDateTime; // uint32_t
//    time_t dwLowDateTime; // uint32_t
//    time_t dwHighDateTime; // uint32_t
    LONLAT_t coords;        // Coordinates:
}

/// ...
read4bytes(&buffer, &h.coords.minLat);

Nebo:

typedef struct HEADER_ {
    uint32_t dwLowDateTime; // uint32_t
    uint32_t dwHighDateTime; // uint32_t
//    time_t dwLowDateTime; // uint32_t
//    time_t dwHighDateTime; // uint32_t
    uint32_t coords[4]; // Coordinates:
}
Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
8. 3. 2015   #51
-
0
-

#50 KIIV
Protože coords nejsou souřadnice v úhlech ve správném slova smyslu.

coords[0] je integer (asi unsigned) ze kterého se vypočítávají bounding coordinates (tak jsem pochopil tu funkci). čili LONLAT_t lze použít až pro ukládání výsledných souřadnic ve stupních. Původní kód to ukládal do pole a já to předělal na struct. Chápu tu funkci tak, že extrahuje nebo vypočítává 4 čísla float z jednoho integeru. Moc do nedává smysl, ale je to tak.

Asi to chce odstranit ampersand, jenže pak nedostanu výsledek. To bych musel udělat talší funkci read4bytes která bude pracovat se dvěma pointerama...

    GetBoundingCoordinates(h.coords[0], &geoloc[0] );
    GetBoundingCoordinates(h.coords[1], &geoloc[1] );
    GetBoundingCoordinates(h.coords[2], &geoloc[2] );
    GetBoundingCoordinates(h.coords[3], &geoloc[3] );

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
8. 3. 2015   #52
-
+1
-
Zajímavé

tak tam nech ty 4 uinty, nedavej tam 4 pointery na uinty

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #53
-
0
-

Ještě bych potřeboval dořešit příspěvek #46 proč mi krachuje datum na posledním řádku

    char date1[25],date2[25];
    struct tm* tm_info;

    uint32_t dwLowDateTime;

    dwLowDateTime=3675431915;

    tm_info = localtime(&h.dwLowDateTime);
    strftime(date1, 25, "%Y:%m:%d%H:%M:%S", localtime(&h.dwLowDateTime));

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #54
-
0
-

#53 oxidián
me to funguje. Kazdopadne pro vicevlaknovou aplikaci ten localtime pouzit nemuzes.

#include <time.h>
#include <stdio.h>
#include <stdint.h>

int main() {
    char date1[25],date2[25];
    struct tm tm_info;

    time_t dwHighDateTime = 1675431915;

    localtime_r(&dwHighDateTime, &tm_info); // reentrant version - for thread safe operations
    strftime(date1, 25, "%Y:%m:%d %H:%M:%S", &tm_info);

    printf("%s\n",date1);
    return 0;
}
Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #55
-
0
-

   

    tm_info = localtime(&h.dwLowDateTime);
    strftime(date1, 25, "%Y:%m:%d%H:%M:%S", &h.dwLowDateTime);
    printf(date1);


tiskne

4997:97:0155:53(\

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #56
-
0
-

proc tam davas ten h.dwLowDateTime? Nehlasi to aspon nejakej warning o predavani uplne blbyho pointeru?

Proste budes muset kompilovat s  -Wall -Werror -pedantic  a zadny nesmysly ani neprojdou pres kompilaci

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #57
-
0
-

No vlastně celé je to takto:

HEADER_t h;

typedef struct HEADER_ {
    uint32_t magicno1;
    uint32_t header_size;
    uint32_t dwLowDateTime; // uint32_t
    uint32_t dwHighDateTime; // uint32_t
    uint32_t magicno2;
    uint32_t sections_count; // following this header
    uint32_t coords[6]; // Coordinates
    uint32_t someempty[2]; // some subareas, meanning unknown, usually 0
} HEADER_t;

a čas je uložen v dwLowDateTime ne ten druhý co jsem špatně zkopíroval

hlášky

warning: passing argument 1 of 'localtime' makes pointer from integer without a cast [enabled by default]|

time.h|121|note: expected 'const time_t *' but argument is of type 'uint32_t'|

warning: passing argument 4 of 'strftime' makes pointer from integer without a cast [enabled by default]|

note: expected 'const struct tm *' but argument is of type 'uint32_t'|

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #58
-
0
-

A jakto ze to tam nevidis?  Predavas uint32_t a ceka to aspon pointer (idealne time_t *) - to je ta hlaska ze delas z cisla pointer.

U druheho delas dokonce z cisla pointer na tu struct tm. Ceka to, ze tomu predhodis  struct tm*  ale ty tomu cpes uint32_t.

Precti si ty warningy poradne (idealni je pochopit, co ti rikaji)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #59
-
0
-
Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #60
-
0
-

muzes predat:   &nejakej_uint  aspon to bude blize pointeru nez nejaka nahodna pozice v ram

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #61
-
0
-

No a co toto:

  uint32_t rawtime=3675431915;
  struct tm * timeinfo;

  // time (&rawtime);
  timeinfo = localtime (&rawtime);
  printf ("Time and date: %s", asctime(timeinfo));

time.h|121|note: expected 'const time_t *' but argument is of type 'uint32_t *'

Prostě se ptám jak dostat unsigned integer to do toho localtime?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #62
-
0
-

da se pouzit explicitni pretypovani ..    (const time_t *)&rawtime

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #63
-
0
-

No jo ale zase to krachuje (asctime)

timeinfo = localtime ((const time_t *) &rawtime);
printf ("Time and date: %s", asctime(timeinfo));

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #64
-
0
-

u me to jede.. asi se budes muset naucit pouzivat poradne debugger.. takhle to dohromady nedas

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #65
-
0
-

Tohle že ti jede???

  uint32_t rawtime=3675431915;
  struct tm * timeinfo;
  timeinfo = localtime ((const time_t *) &rawtime);
  asctime(timeinfo);
Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 3. 2015   #66
-
0
-

#65 oxidián
 

#include <stdio.h>
#include <stdint.h>
#include <time.h>


int main() {
  uint32_t rawtime=3675431915;
  struct tm * timeinfo;

  timeinfo = localtime ((time_t *)&rawtime);
  printf ("Time and date: %s\n", asctime(timeinfo));
}


ano jede

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 3. 2015   #67
-
0
-

Je nějaké jiné řešení, které by mi nekrachovalo? Chybové hlášky jsem už odstranil, ale pointer timeinfo je null
 

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
12. 3. 2015   #68
-
0
-

Ano, je jine reseni - pouzit tu bezpecnejsi verzi pokud to chces pouzit ve vice vlaknech:

    struct tm tm_info;
    localtime_r((time_t *)&rawtime, &tm_info);

Nicmene treba mas jeste nejakou starou ci blbou verzi kompilatoru, treba v nem time_t je jeste porad signed int a maximalni hodnota je kolem roku 2038

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
12. 3. 2015   #69
-
0
-

A pokud bys zabrousil do taju google, tak localtime vracejici null nejspis taky nastavuje errno.

Tak si ho vypis treba pomoci perror (ci strerror).

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
12. 3. 2015   #70
-
0
-

Nevrací žádnou chybu. Chyba je v nesprávném tvaru čísla. Prostě je to unsigned integer a ta funkce očekává signed. Už to neřeším. Končím.

Nahlásit jako SPAM
IP: 78.45.199.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 113 hostů

Podobná vlákna

Pár dotazů k VS — založil yaqwsx

Par dotazu — založil Steve-o-

GUI - pár dotazů — založil Hoptile12

Par dotazu k DirectX a C++ obecne — založil CommanderZ

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý