[c++] funkcja zwraca zły wynik


(rafalski) #1

Witam! Potrzebuję funkcji, która z liczby binarnej przekazywanej przez stringa zrobi dziesiętną.

Wiem jak to przeliczyć, ale mam jakiś problem z funkcją.

string tab;

   tab="010";


   int wynik=0;


  wynik=tab[0];


   return wynik;

Dlaczego zwraca 48 a nie 1? Proszę o pomoc.


(Jawor87) #2

Zwraca 48 ponieważ taki jest kod ASCII dla cyfry 0. Jeżeli chcesz uzyskać wartość zamiast kodu ASCII musisz użyć funkcji "atoi ( const char * str );" .


([alex]) #3

string tab("010");

return tab[0]-'0';


(rafalski) #4

Jednak proszę o pomoc, bo wciąż się męczę, funkcja wygląda następująco

int konwdzies()

{

    string liczba;

    liczba="010";

    int wynik;


    for(int i=0; i
    {


            wynik+=(liczba[i])*(2^(liczba.size()-i)); 


    }

    return wynik;


}

#5

po prostu od każdego liczba odejmij wartość '0'

czyli zamiast liczba napisz liczba__-'0'

Kilka dni temu robiłem konwerter systemów liczbowych i miałem ten sam problem :smiley:


(rafalski) #6

No dobrze, to z tym sobie poradziłem, ale pojawił się inny problem:

#include 

#include 

#include 

#include 

#include 



using namespace std;


string IntToStr(int a) //konwersja int na str

{

       string tmp;

       itoa(a, (char*)tmp.c_str(), 10);

       string str = tmp.c_str();

       return str;

}


int zamascii(char a) //zamiana litery na ASCII

{

    return int(a);

}


string konwbin(int liczba) //zamiana dziesiątkowego na binarny

{

       string binarna="";

       string b;

       int wynik;

       while (liczba>0)

       {

             wynik=liczba%2;

             liczba=liczba/2;

             binarna=IntToStr(wynik)+binarna;

       }

       return binarna;     

}


string dopelnienie(string bin) //dopełnienie zerami

{

       string dopelna;

       int size=bin.size();

       for(int i=0; i<25-size; i++)

       {

               dopelna+="0";

       }

       dopelna+=bin;

       return dopelna;

}


string licznik (int a) //LFSR

{

       int tab[25];


        tab[0]=0;

        tab[1]=0;

        tab[2]=0;

        tab[3]=0;

        tab[4]=0;

        tab[5]=0;

        tab[6]=0;

        tab[7]=0;

        tab[8]=0;

        tab[9]=0;

        tab[10]=0;

        tab[11]=0;

        tab[12]=0;

        tab[13]=0;

        tab[14]=0;

        tab[15]=0;

        tab[16]=0;

        tab[17]=0;

        tab[18]=0;

        tab[19]=0;

        tab[20]=0;

        tab[21]=0;

        tab[22]=0;

        tab[23]=0;

        tab[24]=1;


       for(int i=0; i
       {

               int pom;

               pom=tab[0];

               if(tab[2]==0&&tab[24]==0)

               tab[0]=0;


               if(tab[2]==1&&tab[24]==0)

               tab[0]=1;


               if(tab[2]==0&&tab[24]==1)

               tab[0]=1;


               if(tab[2]==1&&tab[24]==1)

               tab[0]=0;


               tab[24]=tab[23];

               tab[23]=tab[22];

               tab[22]=tab[21];

               tab[21]=tab[20];

               tab[20]=tab[19];

               tab[19]=tab[18];

               tab[18]=tab[17];

               tab[17]=tab[16];

               tab[16]=tab[15];

               tab[15]=tab[14];

               tab[14]=tab[13];

               tab[13]=tab[12];

               tab[12]=tab[11];

               tab[11]=tab[10];

               tab[10]=tab[9];

               tab[9]=tab[8];

               tab[8]=tab[7];

               tab[7]=tab[6];

               tab[6]=tab[5];

               tab[5]=tab[4];

               tab[4]=tab[3];

               tab[3]=tab[2];

               tab[2]=tab[1];

               tab[1]=pom;


       }


      string tablica="";


      for (int i=0; i<25; i++)

      {

          tablica+=IntToStr(tab[i]);

      }

      return tablica;  

};


int XOR (int a, int b) //XOR

{

    int c;

    if (a==0&&b==0) c=0;

    if (a==1&&b==1) c=0;

    if (a==0&&b==1) c=1;

    if (a==1&&b==0) c=1;

    return c;

}


int konwdzies(string liczba) //Konwersja na 10

{

    long long int wynik=0;


    for(int i=0; i
    {

            int a; 

            int b;

            a=liczba[i]-'0'; 

            b=pow(2,(liczba.size()-(i+1)));

            wynik+=a*b;       

    }

    return wynik;

}




int main(int argc, char *argv[])

{


    string text;

    string binarnie;

    string key;

    int poxor[25];

    string poxorze;

    cout<<"Podaj wiadomosc do zakodowania\n";

    cin>>text;

    for (int i=0; i
    {

        binarnie=dopelnienie(konwbin(zamascii(text[i]))); //pojedyńcza litera

        key=licznik(i); //jeden klucz

        for(int j=0; j
        {

                int licz1,licz2;

                licz1=binarnie[j]-'0';

                licz2=key[j]-'0';


                poxor[j]=XOR(licz1,licz2);

                poxorze+=poxor[j];


        }


    cout<


    }



    system("PAUSE");

    return EXIT_SUCCESS;

}

[/code]

Dlaczego w stringu poxorze zamiast liczb wpisuje krzaki?


(Sawyer47) #7

1) Nagłówki: cstdlib, cmath jeśli to C++

2) itoa to niestandardowa funkcja

3) Kod wydaje się zdecydowanie za długi, nie wnikałem co dokładnie te funkcje robią, ale przypisania po całej długości tablicy to raczej średni pomysł (czemu nie pętla?)

4) Pisanie do .c_str() to prawdopodobnie bardzo zły pomysł.

5) XOR zwraca wartości numeryczne 0 lub 1 (nie wnikam już w sens ten funkcji i całego programu oraz tego jak zostały napisane) - a więc takie kody ASCII przypisujesz do stringu. Znów, jeśli chcesz mieć kody ASCII '0' i '1' to dodaj do tej wartości '0'. Chociaż tak jak mówię, kod nie wydaje się elegancki, wszystko to dałoby się napisać krócej i wydajniej.


(rafalski) #8

Faktycznie, troszkę naeksperymentowałem. Coś mi nadal nie chce działać i się wykrzacza, ale mniejsza z tym.

Chciałem jeszcze zapytać o jedną rzecz:

Bo napisałem funkcję, która pobiera liczbę w systemie dziesiętnym, przerabia na dwójkowy i zwraca tę dwójkową w stringu. A czy dało by się tak, żeby funcja zwracała liczbę binarną analogicznie, ale w tablicy intów? ...i jak się do tego odwołać. Bym był wdzięczny za frament kodu.


(Sawyer47) #9

Oczywiście, że by się dało. Musiałbyś tylko podjąć parę decyzji - czy zwracać tablicę o stałym rozmiarze, czy dynamicznie obliczać jej rozmiar (a jeśli dynamicznie to czy zwracać również rozmiar czy może zakończyć jakąś specjalną wartością). No i musiałbyś pamiętać o zwalnianiu takiej tablicy gdy już nie będzie potrzebna (std::string ma te zaletę, że sam zarządza potrzebną mu pamięcią).


(rafalski) #10

Rzecz jasna dynamicznie. Czy mogę prosić o przykład kodu?


(Sawyer47) #11

Ale z czym konkretnie masz problem? Obliczyć rozmiar tablicy, zarezerwować ją dynamicznie (skoro chcesz dynamicznie to jeszcze to o czym wspomniałem - czy np. zakończyć ją wartością inną niż 0 i 1 czy osobno zwracać jej rozmiar), wypełnić ją, zwrócić z funkcji. Jeśli chcesz tylko na system dwójkowy to zamiast bawić się w dzielenie i dzielenie modulo możesz użyć przesunięcia bitowego i koniunkcji logicznej do testowania zawartości bitów. Najwięcej się nauczysz, jeśli sam to napiszesz.


(rafalski) #12

Chodzi o trzy rzeczy. Jak zadeklarować tablicę dynamiczną, zwrócić ją i się odwołać?

-- Dodane 04.06.2011 (So) 15:16 --

ew. napisz jak użyć przesunięcia bitowego czy koniunkcji


(Sawyer47) #13

W C++ dynamicznie alokuje się pamięć operatorami new i delete (oraz new [] i delete []):

http://en.wikipedia.org/wiki/New_%28C%2B%2B%29

http://en.wikipedia.org/wiki/Delete_%28C%2B%2B%29

Czyli

int * tablica = new int[20];

w nawiasach kwadratowych może być również zmienna


potem zwyczajnie w funkcji return tablica

ale musisz pamiętać, żeby po zakończeniu używania zwolnić zarezerwowaną na nią pamięć

delete [] tablica;

(rafalski) #14

czyli załóżmy, że mamy tak:

#include 

#include 


using namespace std;


int *tablica(int liczba)

{

    int* tablica = new int[5];

    for(int i=0; i<5; i++)

    {

            tablica[i]=liczba-1;

            liczba--;

    }

    return tablica;

    delete tablica;


}


int main(int argc, char *argv[])

{

    cout<

    system("PAUSE");

    return EXIT_SUCCESS;

}

a jak w funkcji głównej odwołać się od 3 indeksu tablicy?


(Sawyer47) #15

Usuwasz po zakończeniu pracy w ogóle, to co napisałeś jest bez sensu, bo delete w funkcji się nie wykona (a nawet jak już to do kasowania pamięci alokowanej new [] służy delete []).

#include 

#include 


using namespace std;


int *tablica(int liczba)

{

    int* tablica = new int[5];

    for(int i=0; i<5; i++)

    {

            tablica[i] = liczba-1;

            liczba--;

    }

    return tablica;

}


int main(int argc, char *argv[])

{

    int *arr = tablica(5);


    for(int i = 0; i < 5; ++i)

    {

    	cout << arr[i];

    }



    delete [] arr; 

    return EXIT_SUCCESS;

}

Tylko oczywiście jeszcze jakoś trzeba rozwiązać przekazywanie rozmiaru tablicy.