[C] jak převést číslo uložené v poli na integer

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

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

Odeslat příspěvekod H4CK1 15. 10. 2011 20:29

Zdravím. Chtěl bych se zeptat, jak mám převést číslo, které mám uložené v poli, na celé číslo?
Myslím to takhle:
Na vstupu je číslo 199992, které mám uložené v poli:
pole[0]=1, pole[1]=9, pole[2]=9, pole[3]=9, pole[4]=9, pole[5]=2
A potřebuju z toho získat celé číslo 199992, které bych mohl následně dělit, sčítat, odčítat..
Zkoušel jsem to takhle, ale to my háže blbosti:
Kód: Vybrat vše
        cislo = 0;
        nas = 1;
        i = 0;
        while (pocetprv > i)
        {
        cislo = str[i] * nas + cislo;
        nas = nas * 10;
        i = i + 1;
        }
        printf("cislo je %d \n",cislo);


Díky za odpovědi :)
Desktop: i5 2400, GTX960, 8GB RAM, SSD Intel 330
Notebook: Acer Nitro 5, i5 7300HQ, GTX1050Ti
Smartphone: Samsung Galaxy A5 2016
H4CK1
Junior

Odeslat příspěvekod soban 15. 10. 2011 20:54

Záleží zda v tom poli je číslo (int), nebo znak (char)

Pokud je tam int stačí přičítat a násobit, pokud je tam znak tak podle znakové sady to musíš převést na číslo a pak zase násobit a sčítat.
/----------------------------------------\
| Petr Šobáň |
| Olomouc |
\----------------------------------------/
soban
Pokročilý

Odeslat příspěvekod H4CK1 15. 10. 2011 21:02

Co jedna položka v poli, to číslo 0-9. Přesně tak bych to chtěl udělat, násobením a přičítáním. Co je tedy v tom mém zdrojovém kódu špatně a jak to má být? Díky za rychlou reakci.
Desktop: i5 2400, GTX960, 8GB RAM, SSD Intel 330
Notebook: Acer Nitro 5, i5 7300HQ, GTX1050Ti
Smartphone: Samsung Galaxy A5 2016
H4CK1
Junior

Odeslat příspěvekod soban 15. 10. 2011 21:16

Tak třeba takto:

Kód: Vybrat vše

#include <stdio.h>


void main(void)
{

int pole[6];
int i,nas,cislo,delka;

nas=1;
cislo=0;

pole[0]=1;
pole[1]=9;
pole[2]=9;
pole[3]=9;
pole[4]=9;
pole[5]=2;


delka=sizeof(pole)/sizeof(int);

for (i = 1; i < delka; i++) nas *= 10;

for (i = 0; i < delka; i++)
{
   cislo += pole[i]*nas;
   nas /= 10;
}

printf("Zobrazím číslo: %d \n", cislo );

}



Chybička - opravena měl jsem v for omylem "<=" místo "<" -> chybný: for (i = 0; i <= delka; i++)
Naposledy upravil soban dne 16. 10. 2011 01:04, celkově upraveno 1
/----------------------------------------\
| Petr Šobáň |
| Olomouc |
\----------------------------------------/
soban
Pokročilý

Odeslat příspěvekod H4CK1 15. 10. 2011 22:04

Tak změna :D v poli mám ascii kódy čísel a ne rovnou čísla jak jsem si myslel. Jak je převést na čísla a dát tak dokupy jedno celé číslo? Už mě z toho hrabe, máme to jako úkol do školy a nesmíme použít funkci atoi :(. Jak na to?
Desktop: i5 2400, GTX960, 8GB RAM, SSD Intel 330
Notebook: Acer Nitro 5, i5 7300HQ, GTX1050Ti
Smartphone: Samsung Galaxy A5 2016
H4CK1
Junior

Odeslat příspěvekod Wikan 15. 10. 2011 22:37

ascii - 48
Wikan
Moderátor
Uživatelský avatar

Odeslat příspěvekod H4CK1 15. 10. 2011 23:52

Ježiš já sem v*l, dělám to dneska celej den a konečně mě to došlo. Moc díky za pomoc :)
Desktop: i5 2400, GTX960, 8GB RAM, SSD Intel 330
Notebook: Acer Nitro 5, i5 7300HQ, GTX1050Ti
Smartphone: Samsung Galaxy A5 2016
H4CK1
Junior

Odeslat příspěvekod soban 16. 10. 2011 01:02

Jako kdybych se na to neptal :-)

Kód: Vybrat vše
#include <stdio.h>


void main(void)
{

char pole[6];
int i,nas,cislo,delka;

nas=1;
cislo=0;

pole[0]='1';
pole[1]='9';
pole[2]='9';
pole[3]='9';
pole[4]='9';
pole[5]='2';


delka=sizeof(pole)/sizeof(char);


for (i = 1; i < delka; i++) nas *= 10;

for (i = 0; i < delka; i++)
{
        cislo += ((int)pole[i]-(int)'0')*nas;
        nas /= 10;
}

printf("Zobrazím číslo: %d \n", cislo );

}
/----------------------------------------\
| Petr Šobáň |
| Olomouc |
\----------------------------------------/
soban
Pokročilý

Odeslat příspěvekod Fuller009 17. 10. 2011 14:56

Myslím že by se sobanův výpočet dal zjednodušit cca takto:
Kód: Vybrat vše
#include <stdio.h>

void main(void)
{
char pole[6];
int cislo,delka;

cislo=0;

pole[0]='1';
pole[1]='9';
pole[2]='9';
pole[3]='9';
pole[4]='9';
pole[5]='2';

delka=sizeof(pole)/sizeof(char);

for (int i = 0; i < delka; ++i)
{
        //cislo +=cislo * 10 + ((int)pole[i]-(int)'0');
        //Samozřejmně že bez plus. to plus je za násobením. sem lama
        cislo =cislo * 10 + ((int)pole[i]-(int)'0');

}

printf("Zobrazím číslo: %d \n", cislo );
}


V podstatě jde jen o odstranění toho zbytečnýho foru na začátku a toho zbytečného dělení ve druhém foru. Po odstranění těchto 2 "neduhů" by měl být program efektivnější.
Naposledy upravil Fuller009 dne 18. 10. 2011 13:09, celkově upraveno 1
Fuller009
Junior

Odeslat příspěvekod soban 17. 10. 2011 16:41

Jasně....

To je tak když jsem to psal v rychlosti. No víc hlav víc ví......

PS ten for je správně ?
Kód: Vybrat vše
for (int i = 0; i < delka; ++i)
nemá tam být "i++" :-)
/----------------------------------------\
| Petr Šobáň |
| Olomouc |
\----------------------------------------/
soban
Pokročilý

Odeslat příspěvekod Wikan 17. 10. 2011 16:54

i++ a ++i znamená trochu něco jiného (post increment a pre increment), ale tady je to jedno.
Wikan
Moderátor
Uživatelský avatar

Odeslat příspěvekod pucmeloudek 17. 10. 2011 17:31

soban píše:PS ten for je správně ?

Hlavicka foru je spravne, ale ocividne psana od nekoho, kdo se chce odlisovat za kazdou cenu. Zatim jsem nevidel nikoho, kdo by psal inkrementaci do foru takle.
Co ale neni spravne, je += v tele toho foru.
pucmeloudek
Junior

Odeslat příspěvekod Nargon 17. 10. 2011 18:01

To ja uz jsem videl inkrement ve for cyklu psany takhle ++i. Je to o kousicek rychlejsi nez varianta i++, ale temer kazdy programator to pise jako i++, protoze se mu to lip pise. Alespon me teda jo.

A k tomu vykonu, je to fakt jen o zdibicek rychlejsi. A v tom cyklu to mozna optimalizace u prekladu prelozi na stejny kod, takze to ani nepujde poznat.
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 fotoba 17. 10. 2011 18:05

ak su to znaky
tak staci za posledny pridat znak 0= koniec retazca

string[n+1]=0;

a potom len

sscanf(string, "%d",&cislo);
fotoba
Junior

Odeslat příspěvekod soban 17. 10. 2011 19:58

No jo ale jak tam tu nulu přidat ?

Předpokládám že pole znaků je z jiné části programu. Takže by se muselo to pole překopírovat.

Jinak proč by se nemohlo += používat v for ?

Jinak i++ nebo ++i jsem skoušel a fakt to vygeneruje stejnej kod.



Kód: Vybrat vše
   .file   "pokus.c"
   .section   .rodata
.LC0:
   .string   "Zobraz\303\255m \304\215\303\255slo: %d \n"
   .text
   .globl   main
   .type   main, @function
main:
.LFB0:
   .cfi_startproc
   pushq   %rbp
   .cfi_def_cfa_offset 16
   .cfi_offset 6, -16
   movq   %rsp, %rbp
   .cfi_def_cfa_register 6
   subq   $32, %rsp
   movl   $0, -4(%rbp)
   movb   $49, -32(%rbp)
   movb   $57, -31(%rbp)
   movb   $57, -30(%rbp)
   movb   $57, -29(%rbp)
   movb   $57, -28(%rbp)
   movb   $50, -27(%rbp)
   movl   $6, -12(%rbp)
   movl   $0, -8(%rbp)
   jmp   .L2
.L3:
   movl   -4(%rbp), %edx
   movl   %edx, %eax
   sall   $2, %eax
   addl   %edx, %eax
   addl   %eax, %eax
   movl   %eax, %edx
   movl   -8(%rbp), %eax
   cltq
   movzbl   -32(%rbp,%rax), %eax
   movsbl   %al, %eax
   subl   $48, %eax
   addl   %edx, %eax
   addl   %eax, -4(%rbp)
   addl   $1, -8(%rbp)
.L2:
   movl   -8(%rbp), %eax
   cmpl   -12(%rbp), %eax
   jl   .L3
   movl   $.LC0, %eax
   movl   -4(%rbp), %edx
   movl   %edx, %esi
   movq   %rax, %rdi
   movl   $0, %eax
   call   printf
   leave
   .cfi_def_cfa 7, 8
   ret
   .cfi_endproc
.LFE0:
   .size   main, .-main
   .ident   "GCC: (GNU) 4.6.1 20110908 (Red Hat 4.6.1-9)"
   .section   .note.GNU-stack,"",@progbits
/----------------------------------------\
| Petr Šobáň |
| Olomouc |
\----------------------------------------/
soban
Pokročilý

Další stránka

Kdo je online

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