CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Problem z programem

Problem z programem

dział ogólny

Problem z programem

Nowy postprzez Pitek » czwartek, 21 października 2010, 23:09

Witam mam dość nietypowy problem. Mam program generujący ciągi znaków :

KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <fstream.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String tab[36];
String wynik;

tab[0] = "Q";
tab[1] = "W";
tab[2] = "E";
tab[3] = "R";
tab[4] = "T";
tab[5] = "Y";
tab[6] = "U";
tab[7] = "I";
tab[8] = "O";
tab[9] = "P";
tab[10] = "1";
tab[11] = "2";
tab[12] = "3";
tab[13] = "4";
tab[14] = "5";
tab[15] = "6";
tab[16] = "7";
tab[17] = "8";
tab[18] = "9";
tab[19] = "0";
tab[20] = "A";
tab[21] = "S";
tab[22] = "D";
tab[23] = "F";
tab[24] = "G";
tab[25] = "H";
tab[26] = "J";
tab[27] = "K";
tab[28] = "L";
tab[29] = "Z";
tab[30] = "X";
tab[31] = "C";
tab[32] = "V";
tab[33] = "B";
tab[34] = "N";
tab[35] = "M";

 int ile = 0;
 int k;
 String krok;

 for(k = 1; k <= 1000; k++)
 {
   for(int i=0;i<=19;i++)
   {
    Randomize();
    int x = random(35);

    wynik = wynik + tab[x];
   ile++;
   if(i == 19)
   {
     ile = 0;
     krok = IntToStr(k);
     wynik = wynik + " " + krok + " \n";
   }
   if(ile == 4)
   {
     wynik = wynik + "-";
     ile = 0;
   }
  }

  ofstream outfile;
  outfile.open("keys.txt");
  outfile << wynik.t_str();
  outfile.close();
 }
}
//---------------------------------------------------------------------------


Ma być 1000 osobnych ciągów każdy ma zaczynać się od nowej linii (linijka):

KOD cpp:     UKRYJ  
wynik = wynik + " "+krok+" \n";


Gdybym tylko zmienił ją tak jak poniżej to nie jest ich już 1000 tylko jakaś dziwna nigdzie z niczego nie wynikająca ilość :

KOD cpp:     UKRYJ  
wynik = wynik + " " + krok + "\n";


Tak tak chodzi mi o spację przed "\" to mam ich znacznie mniej :o :shock: bo 200
A przy okazji występują co jakiś czas pewne anomalie np. przeniesienie do nowej lini nie zadziała w zamian mam jakieś losowe dwa znaki i następny ciąg w tej samej linii . :cry:
Bardzo proszę o pomoc przy tym he banalnym programie bo nie wiem co się dzieje. :roll:
Chodzi mi też o to aby przy każdym otwarciu programu generowane ciągi były inne ponieważ za każdym razem 10 to ten sam 10 za następnym otwarciem.
Poniżej podaję program wersji skompilowanej.
Bardzo proszę o pomoc. :|


Pozdrawiam pitek3010
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Generator liczb losowych - generowanie kluczy do plliku/

Nowy postprzez Cyfrowy Baron » piątek, 22 października 2010, 08:53

Miałem Ci nawrzucać za ten kod, gdyż zawiera tyle błędów, ale nie chce mi się ich wszystkich wymieniać. Mała uwaga odnośnie generatora liczb losowych. Jeżeli korzystasz z funkcji random(x) to uruchamiasz generator randomize() pisany z małej litery. Dla generatora Randomize() pisanego wielką literą właściwa jest funkcja Random(const x). To ważne żeby uruchomić właściwy generator, w przeciwnym razie uruchamiasz inny generator i z innego losujesz liczby, co w efekcie prowadzi do tego, że program wciąż losuje te same liczby, gdyż właściwy generator nie jest uruchomiony. Poza tym generator wystarczy uruchomić raz np. podczas uruchamiania program w zdarzeniu OnShow, raz zainicjowany już działa i nie ma potrzeby ponownej inicjalizacji, gdyż to nic nie daje.

Jak rozumiem chcesz wygenerować do pliku 1000 kluczy, każdy składający się z 5 bloków po cztery znaki?! Jeżeli tak to masz tutaj gotowe rozwiązanie:

KOD cpp:     UKRYJ  
#include <memory>

//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
 randomize(); // uruchamia generator liczb losowych
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 char tab[] = "QWERTYUIOP1234567890ASDFGHJKLZXCVBNM";
 String wynik = "";
 std::auto_ptr<TStringList> wynikLista (new TStringList);

 int ile = 0;
 int k;

 int nrLinii = 0; // tylko dla celów testowych

 for(k = 1; k <= 1000; k++)
 {
   for(int i = 0; i <= 19; i++)
   {
    int x = random(36);   // tablica składa się z 36 znaków, a nie 35
    wynik = wynik + (String)tab[x];
    ile++;

    if(ile == 4 && i < 16)
    {
     wynik = wynik + "-";
     ile = 0;
    }
   }
   ++nrLinii; /* tylko dla celów testowych
               (String)nrLinii + ":\t"
               służy do sprawdzenia ile linii jest w pliku */

   wynikLista->Add((String)nrLinii + ":\t" + wynik);
   wynik = "";
   ile = 0;
 }

 String fileName = ExtractFilePath(ParamStr(0)) + "keys.txt";
 wynikLista->SaveToFile(fileName);
}


Przeanalizuj dokładnie ten kod, a nauczysz się czegoś nowego. Posłużyłem się tutaj klasą typu TStringList, gdyż ma wszystko co potrzebne do realizacji tego zadania. Gdybyś jednak chciał używać klasy fstream do zapisywanie danych do pliku, to proponuje posłużyć się wektorami - vector - do tworzenia listy kluczy, gdyż ten numer ze znakiem \n nie przejdzie w przypadku zmiennych AnsiString, czy też UnicodeString.


Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Pitek
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z programem

Nowy postprzez Pitek » piątek, 22 października 2010, 10:12

Bardzo dziękuję! Byłem przekonany że zapis
KOD cpp:     UKRYJ  
int x = random(35);
losuje liczby od 0 do 35 z resztą tak wyczytałem na jakiejś stronie z programowania. Jestem w szoku co do prędkości wygenerowania 1000 kluczy poprzednio trwało to kilka sekund a teraz ułamek sekundy. W ogóle to myślałem że problem nie jest tak złożony. Może to o co zapytam będzie trochę śmieszne ale w końcu chce się czegoś nauczyć. Przeanalizowałem kod i już teraz mniej więcej wiem o co chodzi ale chciałbym wiedzieć to dokładnie od kogoś bo mogę potem mieć złe wyobrażenie.
Mianowicie co dokładnie robi ta linijka poniżej:
KOD cpp:     UKRYJ  
 std::auto_ptr<TStringList> wynikLista (new TStringList);


Jeszcze raz bardzo dziękuję za ogromną pomoc!
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

random - zakres losowania, auto_ptr - wzorzec klasy

Nowy postprzez Cyfrowy Baron » piątek, 22 października 2010, 10:27

losuje liczby od 0 do 35 z resztą tak wyczytałem na jakiejś stronie z programowania.


Co do tego, że losowane są liczby od 0 to masz rację, ale losowanych jest tylko 35 liczb więc zakres losowania wynosi 0-34, a Ty potrzebujesz zakresu 0-35. Liczba w nawiasie nie oznacza zakresu, ale ilość losowanych liczb.



Mianowicie co dokładnie robi ta linijka poniżej:

KOD cpp:     UKRYJ  
std::auto_ptr<TStringList> wynikLista (new TStringList);


auto_ptr to wzorzec klasy zadeklarowany w nagłówku <memory>. Przechowuje wskaźnik do zaalokowanego obiektu i dba o to, żeby obiekt na który ten wskaźnik wskazuje został zniszczony wraz ze zniszczeniem wskaźnika, tutaj po opuszczeniu funkcji. Mógłbym to zrobić tak:

KOD cpp:     UKRYJ  
  TStringList *wynikLista = new TStringList;


ale musiałbym zadbać o zniszczenie tego obiektu po jego wykorzystaniu, czyli na końcu funkcji powinienem usunąć obiekt:

KOD cpp:     UKRYJ  
  delete wynikLista;


używając wskaźnika i wzorca klasy nie muszę dbać o niszczenie wskaźnika, gdyż wzorzec sam po sobie posprząta.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Pitek
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z programem

Nowy postprzez Pitek » piątek, 22 października 2010, 10:31

Bardzo dziękuję teraz wszystko jasne, ten drugi zapis odnośnie niszczenia objektu TStingList jest mi znany.
Liczba w nawiasie nie oznacza zakresu, ale ilość losowanych liczb.

W sumie po tym co Pan napisał w swojej wersji programu tak właśnie myślałem.

Bardzo dziękuję!

P.S. Jaka jest różnica pomiędzy:
KOD cpp:     UKRYJ  
wynik = wynik + (String)tab[x];

a
KOD cpp:     UKRYJ  
wynik = wynik + tab[x];

Bo efekt ten sam.
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Problem z programem

Nowy postprzez Cyfrowy Baron » piątek, 22 października 2010, 11:48

P.S. Jaka jest różnica pomiędzy:


Zmienna tab jest typu char a wynik String. Różnica jest taka, że w pierwszym przypadku konwersja na String dokonywana jest jawnie, a w drugim niejawnie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Wczytywanie określonej linii

Nowy postprzez Pitek » piątek, 22 października 2010, 15:03

Nie wiedziałem czy zakładać nowy temat bo ten jest w sumie o tym samym.
Chodzi mi o to jak wczytać z tego stworzonego pliku określoną linię np.5.
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Problem z programem

Nowy postprzez Cyfrowy Baron » piątek, 22 października 2010, 15:51

Należy posłużyć się klasą TStringList tak jak wcześniej, Skoro ta klasa zapisuje do pliku, to potrafi też z tego pliku czytać. Poczytaj sobie o TStringList w serwisie Cyfrowy Baron w dziale: porady ->TStringList.

KOD cpp:     UKRYJ  
 std::auto_ptr<TStringList> KeysFile (new TStringList);
  String fileName = ExtractFilePath(ParamStr(0)) + "keys.txt";
  KeysFile->LoadFromFile(fileName);
  String key = KeysFile->Strings[5]; //zwraca zawartość wiersza nr. 5
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości