» »

[C++] vprašanja

[C++] vprašanja

fx ::

Štos je v tem da bi jaz ukaz x+150 rad spravil v dva bajta. to se pravi prvi trije znaki v en bajt (x+1) in ostala dva znaka pa v drugi bajt. To gre samo z seštevanjem in premikom v levo.
polje je tipa string
stevilka1 je tipa int
To sem naredil tako :
če je polje[0] == 'x' potem os = 0x01 << 4. 
če je polje[0] == 'y' potem os = 0x02 << 4.
če je polje[0] == 'z' potem os = 0x03 << 4.
če je polje[1] == '+' potem predznak = 0x00 // ni treba premika
če je polje[1] == '-' potem predznak = 0x08 << 4.
če je polje[2] < 3 in polje[2] > 0 potem stevilka1 = polje[2]
/*tu pa pride do napake, ker mi ven vrže v tem primeru 0x31 = 49 to pa je ASCII koda za znak 1*/
ker po pravilnem poteku bi morala biti tako 
os(0x10) + predznak (0x00) + stevilka1 (0x01) = 0x11 (to je 17) // pravilni potek 
os(0x10) + predznak (0x00) + stevilka1(0x31) = 0x41 (to je 65 ) //napačni potek

V glavne morem to številko 1 spraviti v 0x01 in potem bo to delovalo.
Upam da sem bil dovolj razumljiv, kaj za problema imam, če nisem bom naslednjič priložil izvirno kodo.

"Naj živi linux"

noraguta ::

pišeš v heksu , bitwise operatorji opstajajo. binarna notacija pje preprosto prenerodna za brat. sicer pa mi ni čisto jasno kaj hočeš ,če je cifra tipa int je 4 byte , če hočeš 1 byte števko imaš na razpolago unsigned short in shot.
Pust' ot pobyedy k pobyedye vyedyot!

fx ::

zgoraj sem pozabil napisati, da je ukaz x+150 tipa string in to je v polju[]. Jaz bi rad to naredil, da iz stringa dobim številko takošno kakršno ima pač vrednost. Torej če so v ukazu cifre bi te cifre spremeno v decimalno vrednost ne pa v ASCII (če je noter 1, hočem da spremenljika stevilka1 dobi tudi vrednost 1, če je 2 dobi 2 itd, odvisno od cifre).

noraguta, koliko jaz vem ti ena številka zavzeme od 0 do 9 štiri bite
dec = bin; 0 = 0000; 1 = 0001; 2 = 0010; 3 = 0011; 4 = 0100; ...
torej dvo mestno število ti zavzeme en byte. 41(dec) = 0100 0001(bin), če ne verjameš preveri (nočem te želiti).

"Naj živi Linux"

Zgodovina sprememb…

  • spremenil: fx ()

Vesoljc ::

v en bajt lahko spravis malce vec kot samo dvomestno stevilo ;)

tvoj nacin pretvarjanja je rahlo drugacen. namrec vsak znak poskusas zakodirati sz 4 biti. zs tem v biti ni nic narobe, recimo. ampak "normlna" pot pretvarjanja iz dec v bin je taka. in 41 dec je 101001 bin. ne verjames? preveri! zazeni calc.exe, napisi notri 41, ter pritisni bin...
Abnormal behavior of abnormal brain makes me normal...

fx ::

jaz sem zdaj vse pretvarjenja vrgel v en koš. Ta moj sistem ki sem ga napisal je iz hex > bin oz. bin > hex ne pa za dec - moja napaka. Vem da če želiš decimalno število dobiti v bin da je treba deliti.
A je to sploh možno:

Jaz bi rad to naredil, da iz stringa dobim številko takošno kakršno ima pač vrednost. Torej če so v ukazu cifre bi te cifre spremeno v decimalno vrednost ne pa v ASCII (če je noter 1, hočem da spremenljika stevilka1 dobi tudi vrednost 1, če je 2 dobi 2 itd, odvisno od cifre).

"Naj živi Linux"

64202 ::

Hehe :)

Naredis int n = 0;
Potem pa beres input znak po znak in naredis tole za vsakic n *= 10; n += d, kjer je d stevka, ki si jo prebral z inputa ('0' -> 0, '1' -> 1, ...). Tisti n *= 10 pa lahko zamenjas, ce rabis drugo osnovo in pri tem seveda razpoznas drugacen nabor stevk za d.

fx ::

64202 koliko sem te razumle sem naredil tako, kot si mi reko samo mi ni ospelu (poglej v kodo, če sem kje kaj narobe napiso)

koda:

void LPT(std::string polje)
{
int os, predznak, stevilo1, stevilo2, stevilo3, vsota1, vsota2;
bool napaka = false;

cout << "Polje [0] : " << polje[0] << " Polje [1] : " << polje[1] << endl;
cout << "Polje [2] : " << polje[2] << " Polje [3] : " << polje[3] << endl;
cout << "Polje [4] : " << polje[4] << " Polje [5] : " << polje[5] << endl;

/* Prvi znak v ukazu*/
    if (polje[0] == 'x')os = 0x01 << 4;
    if (polje[0] == 'y')os = 0x02 << 4;
    if (polje[0] == 'z')os = 0x03 << 4;
/* Drugi znak v ukazu*/
    if (polje[1] == '+')predznak = 0x00; // ni potebno premakniti v levo
    if (polje[1] == '-')predznak = 0x08 << 4;
/* Tretji, cetrti in perti znaki v ukazu*/
    if ((polje[2] <= '3') or (polje[2] <= '0' ))
       {
       int n = 0;
       n *= 10;
       n += polje[2];
       stevilo1 = n;
       cout << stevilo1 << endl; //samo za test
       napaka = true;
       }
    else
       { Napaka('4'); napaka = false; }

       stevilo2 = polje[3];
       stevilo3 = polje[4];

       vsota1 = os + predznak + stevilo1;
       vsota2 = stevilo2 + stevilo3;

       cout << "Prvi znak   : " << hex << os << endl;
       cout << "Drugi znak  : " << hex <<predznak << endl;
       cout << "Tretji znak : " << hex <<stevilo1 << endl;
       cout << "--------------------" << endl;
       cout << "1. skupaj   : " << hex << vsota1 << endl;
       cout << "--------------------" << endl;
       cout << "Cetrti znak : " << hex << stevilo2 << endl;
       cout << "Peti znak   : " << hex << stevilo3 << endl;
       cout << "--------------------" << endl;
       cout << "2. skupaj   : " << hex << vsota2 << endl;
       cout << "--------------------" << endl << endl;
}


To je to: naredil sem kot si reko pa mi isto dela kot prej.

lp

"Naj živi linux"

fx ::

Problem sem rešil, lahko rečem zelo elegantno :) tu je čudežna rešitev:
int x,i;
std::string znak;
x = (znak[i] - 0x30) 


Zdaj pa še potrebujemo razlago:
bom kar na primeru, če ima znak[0] vrednost 49 ali 0x31 kar je enako ASCII znaku 1.
Če dobro pogledamo imamo kar številko ena v sami hexa kodi to samo pomeni da ji odštejemo 0x30 in dobimo številko 1.

Da ne boste mislili da sem na to idejo prišel iz prve sem prej sestavil tole kodo, ki pa je ne bom opisoval - razen če koga kaj zanima.

int x,i;
std::string znak;
x = (((znak[i] << 4)- 0x300) >> 4);


lp

fx

"Naj živi UNIX"

Zgodovina sprememb…

  • spremenil: fx ()

fx ::

void LPT(std::string polje)
{
int os, predznak, stevilo1, stevilo2, stevilo3;
bool port = false;
/* Prvi znak v ukazu*/
    if (polje[0] == 'x') os = 0x10; // vrednost 0x01 << 4
    if (polje[0] == 'y') os = 0x20; // vrednost 0x02 << 4
    if (polje[0] == 'z') os = 0x30; // vrednost 0x03 << 4
    if (polje[0] == 'r') os = 0x40; // vrednost 0x04 << 4
/* Drugi znak v ukazu*/
    if (polje[1] == '+') predznak = 0x00; // ni potrebno premikati
    if (polje[1] == '-') predznak = 0x80; // vrednost 0x08 << 4
/* Tretji, cetrti in perti znaki v ukazu*/
   if ((polje[2] <= '3') or (polje[2] <= '0' ))
      {
       stevilo1 = polje[2] - 0x30;
       port = true;
       }
    else
       { Napaka('4'); port = false; }

       stevilo2 = polje[3] - 0x30; //primer 0x31 - 0x30 = 0x01
       stevilo3 = polje[4] - 0x30; //primer 0x39 - 0x30 = 0x09

       stevilo1 = os + predznak  + stevilo1;
       stevilo2 = (stevilo2 << 4) + stevilo3;

     if (port == true)
     {
     FILE *lpt;
     lpt = fopen("/dev/lp0" , "w+");
     putc(stevilo1, lpt);
     fclose(lpt);

     putc(stevilo2, lpt);
     fclose(lpt);
     }
}


Imam problem, program se mi noče vrniti iz te funkcije. Ko dam od (če je port == true) v komentar se mi program vrne ko pa dam ven iz komentarja pa se mi ne vrne. In naredil sem kot je prikazano.

lp

"Naj živi UNIX"

OwcA ::

Tisti dvojni fclose(lpt); verjetno ne pomaga zelo.

Če že govoriš o C++, čemu ga potem tudi ne pišeš?
Otroška radovednost - gonilo napredka.

fx ::

Tudi če je samo en fclose(lpt); isto naredi.
Delam pa v C++.

A mogoče obstaja kaki drugi način za pošiljanje podatkov na LPT port, ker to uporabljam namreč za pošiljanje podatkov na že imenovani port.

lp

"Naj živi UNIX"

napsy ::

mpajzl, si kdaj preveril kakšno vrednost vrne fopen?
"If you die, you die. But when you live you live. There is no time to waste."

prehlajeni ::

Ojla!

en zeloo frišn v visual c++ prosi, ce mu lahko kdo pokaze kak primer kako se pravilno uporabi funkcijo WinExec ali CreateProcess za izvrševanje "Command Promt ukaza" recimo copy c:\test.txt c:\test\ ,to je samo primer, s tem ne zelim kopirati fajle ampak izvrševat druge Command Promt ukaze.

HVALA HVALA, lp

Vesoljc ::

lahko tudi poguglas za funkcijo ShellExecute/ex
Abnormal behavior of abnormal brain makes me normal...

prehlajeni ::

...zakaj to ne dela?? :'(


#include *shellapi.h* //zvezdice so namesto ostrih oklepajev zaradi foruma
int main(void)
{
HINSTANCE h = ShellExecute( NULL, "open", "copy c:\test.txt c:\test\", NULL, NULL, SW_SHOW );

return 0;

}

Zgodovina sprememb…

fx ::

struct oseba 
{
 int sifra;
 char priimek[30];
 int starost;
};

bool VnesiOsebo(oseba& o)
{
   cin >> o.sifra;
   
   if (cin.eof())
   {
      cin.clear(); // resetiramo eof bit
      return false; 
   }
   
   cin.get(); // preberemo vejico
  // cin.eatwhite(); // preskocimo preseldek
   
   cin.getline(o.priimek, 30, ',');
  // cin.eatwhite(); // preskocimo presledek
   
   cin >> o.starost;
   cin.get(); // preberemo konec vrstice
   
   // vrnemo stanje enoti cin
   if (cin.good())
      return true;
   else 
      return false;
}


void DodajajOsebe(char* ime_datoteke)
{
   cout << "Vnesite sifr (> 0), ime in starost osebe: " << endl;
   cout << "? ";
   
   oseba nova;
   long zadnja_sifra;
   while(VnesiOsebo(nova) == true)
   {
     fstream osebe(ime_datoteke, ios::in | ios::out);
     
     osebe.seekp(0, ios::end);
     zadnja_sifra = osebe.tellp() / sizeof(oseba);
     if (zadnja_sifra < nova.sifra - 1)
     {
       oseba prazna = {0, "" , 0};
       for (long i = zadnja_sifra + 1; i < nova.sifra; i++)
           osebe.write((char*)&prazna, sizeof(oseba));
     }
     else
        osebe.seekp((nova.sifra - 1) * sizeof(oseba));
        
     osebe.write((char*)&nova, sizeof(oseba));
     cout << "? ";    
   }   
}

Kaj je narobe, ko pritisnem na tipko e bi mi moralo mi program moral vrniti vrednost flase, ampak mi program začne izpisovati v neskončni zanki "Vnesite sifr (> 0), ime in starost osebe: " in se ne ustavi, razen če pritisnem ctrl+c, pol pa tako ali tako program zaključim.

lp

"Naj živi UNIX"

Zgodovina sprememb…

  • spremenil: fx ()

Vesoljc ::

iz te kode ni vidno kje je napaka...
ce pa ti stalno izpisuje tole:
cout << "Vnesite sifr (> 0), ime in starost osebe: " << endl;

ti pa stalno klice funkcijo dodajanjeosebe
Abnormal behavior of abnormal brain makes me normal...

fx ::

V pascalu imam ukaz vrednost := mem[$0040:0017], to je ukaz da gleda stanje tipkovnice. Mene pa zdaj zanima, kako pa to gre v C++ za isto foro.

lp

"Naj živi UNIX"

jype ::

Na katerem sistemu bi pa tole bilo?

Ker na vsakemu modernemu sistemu take reci zalostno propadejo, ker NE SMES packat po hardveru (in sistem ti tega tudi ne bo dovolil).

Vprasaj driver za tipkovnico, kaj se dogaja z njo.

fx ::

A zato mi program v XP-jih ni želel premikati lučke po tipkovnici, ker v 98 pa je šlo brez problema.

Delam v Linux SuSE 9.0 pro.
Zakaj pa mi OS mi nebi dovolil branje, ker bi samo rad preveril ali je bila katera tipka na tipkovnici pritisnjena, med tem ko je program bral iz doc in pošiljal na serijski port.

lp

"Naj živi UNIX"

fx ::

Mene pa samo zanima če C++ pozna naključna števila ?

lp

"Naj živi UNIX"

OwcA ::

Do neke mere (generator v cmath je psevdonaključen).
Otroška radovednost - gonilo napredka.

fx ::

To je potem to :
int r_stev, zm;
r_stev=rand()%zm;

"UNIX je zakon"

Gundolf ::

Pa se tole, ce noces imeti vedno istega pseudorandom zaporedja
#include <time.h>

// in potem pred prvo uporabo rand()
srand((unsigned)time(NULL)); 

fx ::

kako bi ta ukaz:
niz[i] := chr(ord(niz[i]) xor (random(128) or 128); prevedel v c++

predvsem imam težave z chr in ord ker v c+ ne najdem primerna ukaza.
ord ti vrne vrednost znaka , chr pa ti vrne znak glede na številko,
random (128) nevem kako bi opisal, ker nevem kaj dela, vem samo da je naključno stevilo.

lp

"UNIX je zakon"

Gundolf ::

chr in ord sta v c++ odvec,
random(128) nadomestis s (rand()%128) (nekaj postov nazaj ti pise kako se uporablja rand)s
xor se pa prevede v ^
or pa v |

lp

"C++ je zakon"

fx ::

Gre to z c++ narediti da ti program shranjuje ruski nabor znakov v datoteko, ven pa ti zopet prebere slovenski nabor znakov.

lp

"UNIX je zakon"

Gundolf ::

Gre to z c++ narediti da ti program shranjuje ruski nabor znakov v datoteko, ven pa ti zopet prebere slovenski nabor znakov.


Emmmm, kaj?

fx ::

Primer:
jaz vtipkam TEST program pa v datoteko shrani tole ЕУЫЕ, ko pa ven prebere pa zopet prebere TEST.

Želim napisati program ki bo zakodiral podatke.

lp

"UNIX je zakon"

Gundolf ::

Se vedno ne vidim povezave z ruskim naborom znakov.

Vsak znak ni nic drugega kot navadna cifra. Ce delas v ASCII je to 8bitna. Kako jo interpretiras je cisto tvoja stvar (windows 1250, ISO8859-2, UTF-8, ...). To je ena vrsta 'kodiranja'.

Druga vrsta pa je spreminjanje znaka (stevilke), tako da nekdo drug ne bo vedel za kater znak gre. To lahko naredis npr. s funkcijo xor. Ko pises v fajl reces: zapisano = original ^ 105, ko beres pa original = zapisano ^105.

Moonman ::

Zdaj bi pa še jaz rabil vaš nasvet:8)
Imam narediti program, ki bo med drugim izračunal aritmetično sredino negativnih in aritmetično sredino pozitivnih števil.
Torej; kako prebrati, koliko je negativnih in koliko pozitivnih?

if (polje[i] < 0)
{ negativna ++; vsotan += polje[i];}
if (polje[i] > 0)
{pozitivna ++; vsotap += polje[i]; }


OwcA ::

Števec za negativna in števec za pozitivna?
Otroška radovednost - gonilo napredka.

Moonman ::

Jap, kako priti do njega?

P.S. Katero literaturo priporočate za začetnika C++?


Gundolf ::

In kaj je narobe s tvojo kodo moonman? Razen tega da ne pozna stevila 0?

Drugace pa priporocam tutoriale na netu.

OwcA ::

Števec ali dva streseš iz rokava. ;)
int stevec_p = 0;
int stevec_n = 0;

Saj bi rekel, da je naprej očitno, ampak že tole bi moralo biti.
Otroška radovednost - gonilo napredka.

fx ::

Gundolf to deluje, kot si mi napiso.

thx.

"UNIX je zakon"

fx ::

Jaz napišem besedilo, ga zakoidram in shranim v datoteko. Ko besedilo preberem iz datoteke in ka dekodiram, pa mi progam vse izpiše v eno vrstico, čeprav jaz v datoteko vpišem vrstico za vrstico.
EOF je za konec datoteke, kako pa je za konec vrstice ?

lp

UNIX je zakon

Gundolf ::

V linuxu je konec vrstice '\n' v winsih "\r\n" (upam da se nisem zmotil v vrstnem redu), na MACu pa '\r'..

Verjetno ne pises pravilno v datoteko.

fx ::

Pišem v ime_datoteke.dat ali bi moral ime_datoteke.txt ?

lp

UNIX je zakon

Gandalfar ::

ime datoteke ne igra vloge

fx ::

Programska koda:

#include <iostream>
#include <string>
#include <ctype.h>
#include <time.h>
#include <fstream>

using namespace std;

void Meni()
{
cout << "|----------MENI----------|\n"
     << "| /setup  - nastavitve   |\n"
     << "| /key    - kodiranje    |\n"
     << "| /end    - konec kod.   |\n"
     << "| /dekey  - dekodiranje  |\n"
     << "| /exit   - izhod        |\n"
     << "|------------------------|\n\n";
}

bool IzberiDoc(char* ime_doc)
{
  char yes_no;
  cout << " Datoteka : ";
  cin.getline(ime_doc, 30, '\n');
  fstream doc(ime_doc, ios::in);
  if (doc.good())
  {
    cout << " Datoteka " << ime_doc << " obstaja!\n"
         << " Ali zbrisem vsebino datoteke [y/n]? ";
    cin >> yes_no;
    cout << '\n';
    if (yes_no == 'y' || yes_no == 'Y')
    {
      fstream doc(ime_doc, ios:: out | ios::trunc);
    }
    return true;
  }

  cout << " Datoteka " << ime_doc << " ne obstaja!\n"
       << " Ali jo ustvarim [y/n]? ";
  cin >> yes_no;
  cout << '\n';
  if (yes_no == 'y' || yes_no == 'Y')
  {
    fstream doc(ime_doc, ios::out);
    if (doc.bad() || doc.fail())
    {
      cout << " Napaka pri odpiranju datoteke " << ime_doc << "!\n";
      return false;
    }
  return true;
  }
return false;
}

void Kodiranje(std::string niz, char* ime_doc)
{
  int dolzina;
  dolzina = niz.length();
  for (int i = 0; i < dolzina; i++)
  {
    niz[i] = niz[i] ^ 128; //samo 128 sprmenite pa imate drugi kljuc za kodiranje
  }
  fstream doc(ime_doc, ios::out | ios::app);
  doc << niz << '\r\n';
}

void Dekodiranje(char* ime_doc)
{
  char znak;
  int dolzina;
  std::string niz;
  fstream doc(ime_doc, ios::in);
  while (!doc.eof())
  {
    znak = doc.get();
    niz += znak;
  }

  dolzina = niz.length();
  for (int i = 0; i < dolzina; i++)
  {
    niz[i] = niz[i] ^ 128; // kljuc mora biti enako kot pri kodiranju
  }
  cout << "Dekodirano besedilo : " << '\n';
  cout << niz << '\n';
  cout << '\n';
}

int main()
{
/////deklaracija spremenljivk////
srand((unsigned)time(NULL));
std::string niz;
bool je_doc = false;
const int vel = 30;
char ime_doc[vel];
/////////////////////////////////
/////glavni program/////
Meni();
do
{
  getline(cin, niz);
  if (niz != "/exit")
  {
    if (niz == "/key")
    {
      if (je_doc == true)
      {
        do
        {
          cout << "> ";
          getline(cin, niz);
          if (niz != "/end")Kodiranje(niz, ime_doc);
        }
        while (niz != "/end");
      }
      else {cout << "Ni izbrane datoteke!\n";}
    }

    if (niz == "/dekey")
    {
      if (je_doc == true)
      {
        Dekodiranje(ime_doc);
      }
      else {cout << "Ni izbrane datoteke!\n";}
    }

    if (niz == "/setup")
    {
      je_doc = IzberiDoc(ime_doc);
    }
  }
}
while (niz != "/exit");
return 0;
}


Program niti v datoteko ne naredi vrstice, mogoče je to kirvo, da jih potem ne more prebrati?

lp

"UNIX je zakon"

Gundolf ::

Ce ze pises v C++ lahko za newline uporabis tudi endl ("\n" je precej Cjevska fora, ceprav ni nic narobe ce jo uporabljas)
cout << "1. vrstica" << endl << "2. vrstica");

Poskusi spremeniti pisanje. Ponavadi se to dela tako, da se enkrat odpre fajl in potem vanj pise, ne pa da ga vsakic na novo odpiras in appendas. To je vse kar sem pogledal v kodi, ker takle spis me ze vnaprej odvrne od pregledovanja.

Aja, pa za ključ si izberi kaj drugega kot 128 :D Vsaj dokler delas z xor-om.

fx ::

Kaj pa je narobe z 128 ključem ?

lp

"UNIX je zakon"

Gundolf ::

ce xoras s 128, bos v vsakem znaku spremenil tocno 1 bit. Pa se to tistega najmanj pomembnega. Ampak ok, sej z xor res ne mores ne vem kako dobro kodirati zadev.

fx ::

To je res, ampak za prvo silo je.

lp

"UNIX je zakon"

BigWhale ::

Za prvo silo je ze ROT13

;>

64202 ::

Za kriptiranje zna biti zanimiv: crypto++. Nisem se uporabljal, ampak zgleda precej P'n'P, ruknes en AES prek bufferja pa je.

Ali pa mogoce tole openssl enc - da vidis kako se to v praksi dela the right way (dobiti kljuc za kriptiranje iz passworda). Na zalost je openssl kot c knjiznica precej tricky za uporabljat. Nikakva dokumentacija, grda c koda, etc.

BigWhale ::

libmcrypt

Gundolf ::

Ps puste fx-u da se sam mal poigra s kriptografijo no.

fx ::

Ok potem pa se grem igrat :) z kriptografijo.

lp

"UNIX & C++ sta zakon"


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Program za C++ jezik

Oddelek: Programska oprema
232767 (1802) popaj113
»

Kako bi naredil en ultra simple programček?

Oddelek: Programiranje
492218 (1499) AtaStrumf
»

C++ & XP

Oddelek: Programiranje
241566 (1173) Exilian
»

C++ in pavza

Oddelek: Programiranje
161150 (911) napsy
»

c++ datoteke

Oddelek: Programiranje
463819 (3308) Vesoljc

Več podobnih tem