Anonymní profil oksi – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Anonymní profil oksi – Programujte.comAnonymní profil oksi – Programujte.com

 

Příspěvky odeslané z IP adresy 78.102.61.–

Delphi › Vytvoření třídy
4. 5. 2018   #220696

Má to být takto?

TestyOrganizer := TTesty.Create(Form1);
TestyOrganizer.readINI; // step 1.
TestyOrganizer.JazykyInitiate;        // step 2.
TestyOrganizer.DynMenu;        // step 3.


To sice zkompiluje ale taky to krachuje UC_HEB2 raised exception ... Resource TTesty not found

Delphi › Vytvoření třídy
4. 5. 2018   #220695

Ne to tam nemám a kam přesně to mám dát?

Delphi › Vytvoření třídy
4. 5. 2018   #220693

Konstruktor jsem odstranil.

dir není inicializovaný, jen se snažím přiřadit dir := ' '; uvnitř té funkce readINI

Delphi › Vytvoření třídy
4. 5. 2018   #220691

Unit Testy  

dir := ' ';

Mě ten pokus o zápis do veřejné proměnné dir typu string krachne s vyjímkou Class EAccessViolation with message Access violation at Adress ... in modul UC_HEB2.exe  Write adress ... process stoped

https://sourceforge.net/projects/uc-heb/files/developer_backups/2018/unfinished/?upload_just_completed=true

verze 2401

Delphi › Vytvoření třídy
4. 5. 2018   #220682

proceduru na načítání ini jsem přesunul do testů, protože během toho načítání ini vytahuji informace o jazycích ze souboru ini. Je tam na to dlouhá smyčka:

  c := maxTestItems-1;
  if (line='[TestyFolders]') and (testyDirFound=true) then
    begin
    TestFolderInfo := TStringList.Create;
    for i:=0 to maxTestFolders-1 do
      begin;
        readln(f,line);
        TestFolderInfo.clear;
        try
          // ExtractStrings([';'],[],PChar(Str),Line)
          ExtractStrings([';'],[],PChar(line), TestFolderInfo);
          if (line='') or ( (line[1]='0') and (trim(line)='0;' ) ) then
            begin
              SubMenuItemsLoaded[i] := false;
              JazykyFolders[i] := '';
              JazykySelected[i] := '';
              continue;
            end;
{
JazykyIndexy - byly iniciovány v
JazykyInitiate. Seznam obsahuje jen prázdné řetězce.
}

          begin
             if (TestFolderInfo.Strings[0][1] = '[') or
             ( length(trim(TestFolderInfo.Strings[0])) = 0 ) then
               break; // ukončit smyčku přidávání jazyků

             Jazyky[i] := TestFolderInfo.Strings[0];

             SubMenuItemsLoaded[i] := true;
             JazykyFolders[i] := TestFolderInfo.Strings[0];
             if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i])) then
                begin
                   CreateDir(TestyDir+'\'+JazykyFolders[i]);
                   showmessage(TestyDir);
                   showmessage('Adresář jsem zkusil vytvořit automaticky: '+TestyDir+'\'+JazykyFolders[i]);
                   ; JazykyFolders[i] := '';
                   SubMenuItemsLoaded[i] := false;
                end
             else
              try
                c := c-1; // potvrdit, že složka s jazykem byla asociována
// Jazyky sub-folder folder specification
// nemá být číslo, ale název adresáře

                if TestFolderInfo.count>2 then
                  JazykySelected[i] :=  TestFolderInfo.Strings[2]
                else
                  JazykySelected[i] := 'textbook';

                if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i])) then
                  begin
                    CreateDir(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                    showmessage('Adresar ucebnice jsem musel vytvorit: '+TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                  end;
              finally
              end;
          end;

         SubMenuItemsLoaded[i] := false
        finally
        end;
      end; // end of for ... begin

    lanCount := i+1;
    TestFolderInfo.Free;
    end;


Ve které se nastavují informace o jazycích. Právě proto jsem vytvořil tu třídu Testy, která má všechny tyto informace zawrapovat.

Pak je tam ještě cesta k souboru s testama, velikost fontů, obtížnost testů.

paramstr nevím kde je definováno

Delphi › Vytvoření třídy
4. 5. 2018   #220679

Další problém který mám je s proměnnou dir.

unit Testy;
...

type
  TTesty = class(TForm)

  public
    dir : string;


...

end;

implementation

uses
  Uc_heb1;

constructor TTesty.Create;
begin
  dir := extractfilepath(paramstr(0));
end;



Když se zavolá konstruktor tak dir se nenastaví (zdá se).

procedure TTesty.readINI;
var line: String;
    f:textfile;
    i, c, size: integer;
    TestFolderInfo: TStrings;
begin
  if not fileexists(dir+'uc_heb.ini') then exit;


Na poslední řádek zarážku a kukátko na dir a není nastaveno. Jde o to zjistit a nastavit pracovní adresář. Když dir není nastaveno tak program spadne

Delphi › Vytvoření třídy
4. 5. 2018   #220677

OK, dík, zkompilováno to je. Teď se to pokusím rozjet.

Delphi › Vytvoření třídy
4. 5. 2018   #220676

do souboru testy.pas?

var TestyOrganizer: TTesty;

end.


TestyOrganizer.readINI; // step 1.


Neznámý identifikátor TestyOrganizer

Delphi › Vytvoření třídy
4. 5. 2018   #220673

V kterém souboru?

Takže to mám vložit před

end.

?

Delphi › Vytvoření třídy
4. 5. 2018   #220669

Teď řeším problém v tom Uc_heb1

Chci volat veřejnou metodu z TTesty:

Testy.readINI; // step 1.
Testy.JazykyInitiate;        // step 2.
Testy.DynMenu;        // step 3.

[Error] UC_HEB1.PAS(541): Undeclared identifier: 'readINI'

[Error] UC_HEB1.PAS(541): Undeclared identifier: 'readINI'

[Error] UC_HEB1.PAS(543): Undeclared identifier: 'DynMenu'

Ty Testy jsou jako globální proměnná ne? Nerozumím tomu proč nevidí ty metody.

Aktuální verze s chybou je zde:

https://sourceforge.net/projects/uc-heb/files/developer_backups/2018/unfinished/ucheb.240.zip/download

Delphi › Vytvoření třídy
4. 5. 2018   #220664

#9 mjseven
Tak tomu tedy říkám zázrak, že je to tak jednoduché. Díky

Delphi › Vytvoření třídy
4. 5. 2018   #220662

Díky. Toto jsem opravil. Další chyba:

unit Uc_heb1;

interface

uses
  WinTypes, WinProcs, Messages, ExtCtrls, Dialogs,
  StdCtrls, Controls, Graphics, Gauges, Classes,
  Forms, Menus, SysUtils,
  Uc_obr2,vyslheb, jmeno, book, Buttons,
  uspech,testfnt, Napoveda,antiwin,otviram,
  functions, konstanty,  FileCtrl, Testy;



Mi píše [Fatal Error] Circular unit reference to 'Uc_heb1'

V testy.pas mám

unit Testy;

interface

uses
  Uc_heb1,

V tom prvním unitu chci volat metodu z toho druhého unitu. Ale druhý unit používá první unit, jak jsem psal.

Jak vzniklou situaci vyřešit?

Delphi › Vytvoření třídy
3. 5. 2018   #220659

Celé je to takto:

if TForm1.allBigger1.checked then writeln(f,'[allBigger]');


A v předchozím přízpěvku jsem to zkrátil proto, abych ukázal na místo v kódu kde to hlásí chybu. Takže nechápu v čem je problém.

Delphi › Vytvoření třídy
3. 5. 2018   #220657

TForm1.allBigger1.

[Error] testy.pas(235): Method identifier expected

???

Delphi › Vytvoření třídy
3. 5. 2018   #220653

Aplikace

uc_heb1.pas:

unit Uc_heb1;
interface

uses
  WinTypes, WinProcs, Messages, ExtCtrls, Dialogs,
  StdCtrls, Controls, Graphics, Gauges, Classes,
  Forms, Menus, SysUtils,
  Uc_obr2,vyslheb, jmeno, book, Buttons,
  uspech,testfnt, Napoveda,antiwin,otviram,
  functions, konstanty,
  FileCtrl;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;

....
    allBigger1: TMenuItem;
...
end.

implementation ...

testy.pas:

 

unit Testy;

interface

uses
  WinTypes, WinProcs, Messages, ExtCtrls, Dialogs,
  StdCtrls, Controls, Classes, // Graphics, Gauges, 
  Forms, Menus, SysUtils,
  Uc_obr2,vyslheb, jmeno, book, Buttons,
//  uspech,testfnt, Napoveda,antiwin,otviram,
  functions, konstanty,
  FileCtrl;

type
  TTesty = class(TForm)
  private
    dir : string;
    i: integer;
    Nic: TMenuItem;
    N1: TMenuItem;

    langMenuItems : array of TMenuItem;
    SubMenuItems : Array of TMenuItem;
    SubMenuItemsLoaded : Array [0..maxTestItems-1] of boolean;
    TestyDirs, SubDirs : TStringList; // for folders search
    procedure readINI;
    procedure writeINI;
    procedure JazykyInitiate;
    procedure DynMenu;
    procedure upravmenu;
  public
    allBigger, skipFontTest, fontSizeSmall, fontSizeNormal, fontSizeLarge,
    difficultyEasy, difficultyNormal, difficultyHarder, difficultyHard,
    testyDirFound : Boolean;
    TestyDir : string;

    fileMenu: array [0..maxRecentFiles-1] of string;

    JazykyIndexy : TStrings;
    Jazyky : Array [0..maxTestItems-1] of string; // Language names ... associated with JazykyFolders
    JazykyFolders : Array [0..maxTestItems-1] of string; // Folder names associated with Jazyky menu items
    JazykySelected : Array [0..maxTestItems-1] of string; // Jazyky sub-folder folder specification
  end;

implementation

procedure TTesty.upravmenu;
var curFile: TMenuItem;
    i : integer;

begin

  for i:=1 to maxRecentFiles do
    begin
    if i=1 then
      begin
        if fileMenu[0]<>'' then N1.visible:=true
        else N1.visible:=false;
      end;

    curFile := FindComponent('file'+IntToStr(i*10 + 1)) as TMenuItem;
    if fileMenu[i-1]<>'' then
      begin
        curFile.visible := true;
        curFile.caption:=extractfilename(fileMenu[i-1]);
      end
    else
      curFile.visible := false;

    end; // end for
end;

procedure TTesty.readINI;
var line: String;
    f:textfile;
    i, c, size: integer;
    TestFolderInfo: TStrings;
begin
  if not fileexists(dir+'uc_heb.ini') then exit;
  try
    assignfile(f,dir+'uc_heb.ini');
    reset(f);
  except
    showmessage('Nelze otevrit soubor .ini s nastavenim.');
  end;
  if filesize(f)<1 then
     begin
     showmessage('Soubor .ini neobsahuje text.' );
     exit;
     end;

  allBigger := false;
  skipFontTest := false;
  repeat
    readln(f,line);
    if line[1]='[' then
    begin;
      if line='[allBigger]' then allBigger:=true;
      if line='[skipFontTest]' then skipFontTest:=true;
      if line='[fontSmall]' then fontSizeSmall := true
        else if line='[fontNormal]' then fontSizeNormal := true
        else if line='[fontLarge]' then fontSizeLarge := true;
      if line='[difficultyEasy]' then difficultyEasy := true
        else if line='[difficultyNormal]' then difficultyNormal := true
        else if line='[difficultyHarder]' then difficultyHarder := true
        else if line='[difficultyHard]' then difficultyHard := true;
    end;
  until (line='[TestyDir]') or (line='[TestyFolders]') or eof(f);

  testyDirFound := false;
  if line='[TestyDir]' then
    begin
     readln(f,TestyDir);
     if DirectoryExists(TestyDir) then
       testyDirFound := true;
     readln(f,line);
    end;

  c := maxTestItems-1;
  if (line='[TestyFolders]') and (testyDirFound=true) then
    begin
    TestFolderInfo := TStringList.Create;
    for i:=0 to maxTestFolders-1 do
      begin;
        readln(f,line);
        TestFolderInfo.clear;
        try
          // ExtractStrings([';'],[],PChar(Str),Line)
          ExtractStrings([';'],[],PChar(line), TestFolderInfo);
          if (line='') or ( (line[1]='0') and (trim(line)='0;' ) ) then
            begin
              SubMenuItemsLoaded[i] := false;
              JazykyFolders[i] := '';
              JazykySelected[i] := '';
              continue;
            end;
{
JazykyIndexy - byly iniciovány v
JazykyInitiate. Seznam obsahuje jen prázdné řetězce.
}



{
NESMYSL! JazykyIndexy JEŠTĚ NENÍ PŘIPRAVENO!
          if ( TestFolderInfo.count > 0 ) then
            pos := JazykyIndexy.IndexOf(TestFolderInfo.Strings[0])
          else
            pos := -1;
}

          begin
             if (TestFolderInfo.Strings[0][1] = '[') or
             ( length(trim(TestFolderInfo.Strings[0])) = 0 ) then
               break; // ukončit smyčku přidávání jazyků

             Jazyky[i] := TestFolderInfo.Strings[0];

             SubMenuItemsLoaded[i] := true;
             JazykyFolders[i] := TestFolderInfo.Strings[0];
             if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i])) then
                begin
                   CreateDir(TestyDir+'\'+JazykyFolders[i]);
                   showmessage(TestyDir);
                   showmessage('Adresář jsem zkusil vytvořit automaticky: '+TestyDir+'\'+JazykyFolders[i]);
                   ; JazykyFolders[i] := '';
                   SubMenuItemsLoaded[i] := false;
                end
             else
              try
                c := c-1; // potvrdit, že složka s jazykem byla asociována
// Jazyky sub-folder folder specification
// nemá být číslo, ale název adresáře

                if TestFolderInfo.count>2 then
                  JazykySelected[i] :=  TestFolderInfo.Strings[2]
                else
                  JazykySelected[i] := 'textbook';

                if not (DirectoryExists(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i])) then
                  begin
                    CreateDir(TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                    showmessage('Adresar ucebnice jsem musel vytvorit: '+TestyDir+'\'+JazykyFolders[i]+'\'+JazykySelected[i]);
                  end;
              finally
              end;
          end;

         SubMenuItemsLoaded[i] := false
        finally
        end;
      end; // end of for ... begin

//    setlength( Jazyky, i+1 );
    TestFolderInfo.Free;
    end;

    // prevent crash: initiate arrays for DynMenu
    for i:=0 to maxTestItems-c-1 do
      begin
           JazykyFolders[i] := '';
           SubMenuItemsLoaded[i] := false;
      end;
    // end of else

  repeat
    readln(f,line);
  until ( line='[poslední testy]')  or eof(f);

  if line='[poslední testy]' then
    begin
    for i:=0 to maxRecentFiles-1 do
      fileMenu[i]:='';
    i:=0;
    repeat
      readln(f,fileMenu[i]);
      inc(i);
    until ((fileMenu[i]<>'') or (i=maxRecentFiles-1)) or eof(f);
    end;
  upravmenu;
  closefile(f);  {**************************************** to jsem tam dal ja!!!!}
end;

procedure TTesty.writeINI;
var f:textfile;
    b:boolean;
begin
try
 b:=false;
 assignfile(f,dir+'uc_heb.ini');
 try
   rewrite(f);
   b:=true;
   if allBigger1.checked then writeln(f,'[allBigger]');
   if skipFontTest1.checked then writeln(f,'[skipFontTest]');
   if fontSizeSmall1.checked then writeln(f,'[fontSmall]')
     else if fontSizeNormal1.checked then writeln(f,'[fontNormal]')
     else if fontSizeLarge1.checked then writeln(f,'[fontLarge]');
   if difficultyEasy1.checked then writeln(f,'[difficultyEasy]')
     else if difficultyNormal1.checked then writeln(f,'[difficultyNormal]')
     else if difficultyHarder1.checked then writeln(f,'[difficultyHarder]')
     else if difficultyHard1.checked then writeln(f,'[difficultyHard]');
   writeln(f,'[TestyDir]');
   writeln(f,TestyDir);
   writeln(f,'[TestyFolders]');
   for i:=0 to maxTestFolders-1 do
    begin
      if (Jazyky[i][1]=' ') or (Jazyky[i][1]='-') then
         continue; // skip Test menu Groups or Select
      if JazykySelected[i]='' then
         begin
          writeln(f,Jazyky[i]+';0');
          continue; // submenu not selected - done
         end
      else
         if (JazykySelected[i][1]=' ') or (JazykySelected[i][1]='-') then
           continue; // skip Test sub-menu Groups or Select

      if SubMenuItemsLoaded[i]=true then
        begin
          writeln(f,submenuItems[i].name+';'+JazykyFolders[i]+';'+JazykySelected[i])
        end
      else
        writeln(f,Jazyky[i]+';0');
    end;
   writeln(f,'[poslední testy]');
   for i:=0 to maxRecentFiles-1 do
      if fileMenu[i]<>'' then
        writeln(f,fileMenu[i]);
 except
   showmessage('Nastavení se nepovedlo zapsat.');
 end;
 closefile(f);
except
end;
end;


end.

Chyba: na řádku 234 v souboru testy.pas není známý identifikátor

allBigger1

v souboru uc_heb1.pas je tato definice:

allBigger1: TMenuItem;

je to tedy součást TForm1 ...

A teď mi řekněte jak v té třídě TTesty mám tedy zpřístupnit nebo odkázat na menu, které se používá v té třídě TForm1?

Navíc TTesty má být použito v TForm1.

Delphi › Smyčka for .. in array
3. 5. 2018   #220647

Zrovna teď bych raději vyřešil jak ty jazyky zawrapovat abych se v tom neztratil.

Já treba k tomu poli jazyků nevím kolik těch jazyků tam je. To je problém. Wrapper by se mohl jmenovat Testy a obsahoval by člena langCount kam bych tu informaci uložil během načítání souboru ini.

Delphi › Smyčka for .. in array
3. 5. 2018   #220644

Můžete mi dát příklad jak ty jazyky zabalit do třídy?

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Soubor1: TMenuItem;
  private
    langMenuItems : array of TMenuItem;
    SubMenuItems : Array of TMenuItem;
    SubMenuItemsLoaded : Array [0..maxTestItems-1] of boolean;
    TestyDirs, SubDirs : TStringList; // for folders search
    procedure JazykyInitiate;
    procedure DynMenu;
  public
    JazykyIndexy : TStrings;
    Jazyky : Array [0..maxTestItems-1] of string; // Language names ... associated with JazykyFolders
    JazykyFolders : Array [0..maxTestItems-1] of string; // Folder names associated with Jazyky menu items
    JazykySelected : Array [0..maxTestItems-1] of string; // Jazyky sub-folder folder specification
  end;

K tomu ještě patří

procedure TForm1.readINI;

procedure TForm1.writeINI;

Co potřebuju udělat je, aby procedury a proměnné

.readINI

.writeINI


.JazykyInitiate

.DynMenu
apod. byly pod jednou instancí. Abych ty data, ohledně adresářů, jazyků, knih, vybraných apod. měl vše pod jednou instancí.

Delphi › Smyčka for .. in array
3. 5. 2018   #220643

Nechtěli byste se mi na to mrknout? Chyby co mi to házelo jsem odstranil. Teď pracuji na menu testy.

Jen to spusťte, a klikněte na menu Testy. Tam jsou ty automaticky vytvořené položky. Člověk má vlastně vybrat jeden jazyk, ze kterého chce dělat testy. Je otázka proč tam je tolik prázdných položek dole.

https://sourceforge.net/projects/uc-heb/files/developer_backups/2018/finished/ucheb.24.zip/download

Okruhy přesně si nepamatuji na co jsou, ale měly by tam být ještě učebnice. Po vybrání jazyka se načtou učebnice dostupné pro daný jazyk. Např. jeden jazyk je možné cvičit z různých zdrojů.

Delphi › Smyčka for .. in array
3. 5. 2018   #220642

#7 Sniper
Proč ne? Však tu instanci pak mohu odstranit.

Delphi › Smyčka for .. in array
3. 5. 2018   #220637

#4 MilanL

Našel jsem: "Delphi 7 does not support for .. in"
Mě by to přišlo pohodlnější.

Ano, je to nepřehledné o té nutnosti to zabalit vím. Jen jsem s třídou ještě nedělal, tak to odkládám.

Delphi › Smyčka for .. in array
3. 5. 2018   #220633

Vždyď to tak mám, tak co znamená ta chybová hláška?

 Zapoměl jsem uvést, ale mám to tam:

s: string;
Delphi › Smyčka for .. in array
3. 5. 2018   #220631

Chyba 1.: Operator not applicable to this operand type

Chyba 2.: Expression expected but 'BEGIN' found

// 1. deklarace

Jazyky : Array [0..maxTestItems-1] of string;

// 2. iniciace a načtení dat do Jazyky

// 3. zkouším projít pole stringů

  for s in Jazyky do
    begin

   // some code here

   end;


Nerozumím té chybě. Podle příkladu by to mělo fungovat.

Delphi › nastavení projektu (Borland…
3. 5. 2018   #220629

#3 gna
Nalezl jsem HLEDEJ1.pas

Tak jsem ho tam přidal. Už to jde zkompilovat.

Delphi › nastavení projektu (Borland…
2. 5. 2018   #220627

Myslím si že nějak se stalo že se Form2 nastavil jako hlavní nebo defaultní místo Form1. Form1 by se měl otevřít při otevření projektu, místo toho se otevírá Form2. Jak to napravit?

A jak zjistit kde se definuje TFhledani a Fhledani? A jak to udělat aby program našel tyto položky?

 

Delphi › nastavení projektu (Borland…
2. 5. 2018   #220626

Před několik dny jsem přesunul projekt do jiného adresáře a začal jsem mít problémy.

Teď jsem chtěl uložit projekt a dostával jsem hlášky směřující k jinému projektu. Pak jsem přišel na to, že některé cesty směřovali do toho starého adresáře.

uses
  Forms,
  Uc_heb1 in 'R:\+++Fyzika\Tepelná výmìna\ucheb\UC_HEB1.PAS' {Form1},
  Uc_obr2 in 'R:\+++Fyzika\Tepelná výmìna\ucheb\UC_OBR2.PAS' {AboutBox1},
  Vyslheb in 'R:\+++Fyzika\Tepelná výmìna\ucheb\VYSLHEB.PAS' {Form2},
  Jmeno in 'R:\+++Fyzika\Tepelná výmìna\ucheb\JMENO.PAS' {selectUserDlg},
  Uspech in 'R:\+++Fyzika\Tepelná výmìna\ucheb\USPECH.PAS' {uspsnst},
  Editace in 'R:\+++Fyzika\Tepelná výmìna\ucheb\EDITACE.PAS' {FEditace},
  Novy in 'R:\+++Fyzika\Tepelná výmìna\ucheb\NOVY.PAS' {Novyfrm},
  Vyberfnt in 'R:\+++Fyzika\Tepelná výmìna\ucheb\VYBERFNT.PAS' {VybFont},
  Testfnt in 'R:\+++Fyzika\Tepelná výmìna\ucheb\TESTFNT.PAS' {Ftestfont},
  Napoveda in 'R:\+++Fyzika\Tepelná výmìna\ucheb\NAPOVEDA.PAS' {FNapoveda},
  Hledej2 in 'R:\+++Fyzika\Tepelná výmìna\ucheb\HLEDEJ2.PAS' {Opravduhledani},
  Vbrhlfnt in 'R:\+++Fyzika\Tepelná výmìna\ucheb\VBRHLFNT.PAS' {FVybHledFont},
  Otviram in 'R:\+++Fyzika\Tepelná výmìna\ucheb\OTVIRAM.PAS' {FOtviram},
  Book in 'R:\+++Fyzika\Tepelná výmìna\ucheb\book.pas' {BooksDialog};


Z té tepelné výměny (nevím jak se to tam dostalo)... jsem to přesunul jinam a soubor projektu jsem uložil pod jiným jménem. Normálně by se měl otevřít formulář s aplikací, místo toho se mi teď otevírá jen okno pro ukončení testu. Když dám kompilovat

UC_HEB2

program UC_HEB2;

uses
  Forms,
  Uc_heb1 in 'UC_HEB1.PAS' {Form1},
  Uc_obr2 in 'UC_OBR2.PAS' {AboutBox1},
  Vyslheb in 'VYSLHEB.PAS' {Form2},
  Jmeno in 'JMENO.PAS' {selectUserDlg},
  Uspech in 'USPECH.PAS' {uspsnst},
  Editace in 'EDITACE.PAS' {FEditace},
  Novy in 'NOVY.PAS' {Novyfrm},
  Vyberfnt in 'VYBERFNT.PAS' {VybFont},
  Testfnt in 'TESTFNT.PAS' {Ftestfont},
  Napoveda in 'NAPOVEDA.PAS' {FNapoveda},
  Hledej2 in 'HLEDEJ2.PAS' {Opravduhledani},
  Vbrhlfnt in 'VBRHLFNT.PAS' {FVybHledFont},
  Otviram in 'OTVIRAM.PAS' {FOtviram},
  Book in 'book.pas' {BooksDialog},
  konstanty in 'konstanty.pas',
  functions in 'functions.pas',
  antiwin in 'antiwin.pas';

{$R *.RES}

begin
  Application.CreateForm(TForm2, Form2);
  Application.CreateForm(TBooksDialog, BooksDialog);
  Application.CreateForm(TFEditace, FEditace);
  Application.CreateForm(TFhledani, Fhledani);
  Application.CreateForm(TOpravduhledani, Opravduhledani);
  Application.CreateForm(TSelectUserDlg, SelectUserDlg);
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TFNapoveda, FNapoveda);
  Application.CreateForm(TNovyfrm, Novyfrm);
  Application.CreateForm(TFOtviram, FOtviram);
  Application.CreateForm(TFtestfont, Ftestfont);
  Application.Run;
end.


Dostanu chybovou hlášku, že TFhledání a Fhledání je neznámý identifikátor.

Cesty v projektu jsem nastavil na adresář kde se program nachází nyní.

A dále, nevím co je v tom nastavení Forms.

Main form: Form2 (možná špatně?)

Tam na levé straně mám Auto-create forms:

Form2 a Form1 je mezi nimi.

A vpravo je Avalaible Forms:

AboutBox1 aj. Jaký je rozdíl v těch dvou skupinách?

Dále, k čemu slouží BPL directory a DCP directory, a musím je nastavovat?

Delphi › ExtractStrings a TStrings
2. 5. 2018   #220621

Jak zpřístupnit první znak z položky seznamu?

Raw := TStringList.Create;

// pak přidám data do seznamu

Raw.Strings[0][0]; // teď chci vrátit první znak z první položky
Delphi › Procházení adresáře
2. 5. 2018   #220620

čas od času to zálohuju ručně. Obvykle když něco rozjedu. V Delphi mi to jde pomalu tak asi jednou dvakrát za týden.

Delphi › Procházení adresáře
2. 5. 2018   #220616

Díky moc. Teda ja v původním kódu viděl tu masku, jenže jsem ji odstranil, tak to přestalo fungovat.

Delphi › Procházení adresáře
2. 5. 2018   #220607

Moje funkce

function createTestyDirsList(TestyDir: string):TStringList;
var i: Integer;
  TestyDirs : TStringList; // for folders sreach
  SearchRecord : TSearchRec;
begin
  TestyDirs := TStringList.create();

  if FindFirst(TestyDir,faDirectory,SearchRecord)=0 then
    begin

    while FindNext(SearchRecord) = 0 do
      begin
        if (SearchRecord.Attr = 16 {faDirectory}) and (SearchRecord.Name <> '.') and (SearchRecord.Name<>'..') then
          TestyDirs.Add(SearchRecord.Name);
      end;
    SysUtils.FindClose(SearchRecord);
    end;

  Result := TestyDirs;
end;

Volám ji

TestyDir := "P:\PROGRAMY\programování\PAS\delphi7\Projects\heb\Testy";

TestyDirs := createTestyDirsList(TestyDir);


V tom adresáři mám několik adresářů, ale problém je, že se mi nepřidají do seznamu. To while to completně přeskočí a projde to na SysUtils.FindClose(SearchRecord) ještě než by se cokoliv přidalo.

Delphi › ExtractStrings a TStrings
2. 5. 2018   #220606

#25 MilanL
Čau, no tak já jsem na tom nějakou dobu nedělal, nevím ani kolik uplynulo času.

Delphi › ExtractStrings a TStrings
2. 5. 2018   #220598

Runtime errors: Range checking

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220596

#19 Sniper
Vracím se po dlouhé době k rozdělanému kódu, není lehké zjistit jak jsem to chtěl původně udělat.

maxSubFolders je 255, a původně jsem tam měl repeat .... tak jo mám v tom chaos.

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220595

#20 gna
To ale nevím kde se to zapíná kam to mám zapsat nebo kde to nastavit. To jako v nastavení compilátoru?

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220592

A když mám pole stringů

Jazyky : Array [0..maxTestItems-1] of string; // celkem 11 položek, ale iniciuje se jich jen 10, protože v souboru ze kterou čtu jazyky je jen 10 položek.

provedu iniciaci / načtení jazyků do pole...

A na konci pomocí smyčky přiřazuju str := ...

  for i:=0 to maxSubFolders-1 do
    begin;
    j := length(submenuitems); // i - index submenu
    setlength(submenuitems,j+1);
    str := Jazyky[i];
    // dále zpracuju str...
    // a při 11 položce to krachne
end;


Jak zkontrolovat jestli Jazyky[i] je nastaveno ještě před tím než to zkusím přiřadit tomu str?

Konkrétně mi to dává hlášku: Access violition at address ...

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220590

Díky za rady, já už jsem skoro hotov.

Tohle mi nefunguje:

JazykySelected[pos] := TestFolderInfo.count>1 ? TestFolderInfo.Strings[2] : 0;

[Error] UC_HEB1.PAS(630): Illegal character in input file: '?' ($3F)

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220589

Dobře, tak už chápu. Je to objekt, tedy se k tomu nedá přistupovat jako k poli.

Řeším tedy jak zkopírovat položky do pole nebo jak zkopírovat string z položky i do jiného stringu (tedy jak zpřístupnit ten string pomocí i).

Edit:

Tak zpřístupnit to mohu pomocí

Line.Strings[0], Line.Strings[1]

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220585

Problém s hláškami jsem vyšešil, ale co jsem nevyřešil je ten pTest, proč není přístupný v kukátku uvnitř funkce. Prá nějaká optimalizace.

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220583

#9 gna

No právě: Variable 'ptest' inaccessible here due to optimization

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220581

#7 gna
Vyjímku to nehází, už jsem ten try block odstranil.

V kukátku mám hlášku že proměnná ptest není přistupná due to optimalization

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220578

#4 Sniper
No a mě toto nefunguje:

procedure Foo;
var
  Str:  String;
  Line: TStringList;
  i:    Integer;
begin
  Str := 'Latina;0';
  Line := TStringList.Create;
  ExtractStrings([';'],[],PChar(Str),Line);
  Line.Free;
end;


To jsem jen zkrátil tvůj kód. V kukátku vidím Line = (). Stojím na řádku Line.Free;

procedure Foo;
var
  Str:  String;
  Line: TStringList;
  i:    Integer;
  ptest: PChar; // console: warning Unsafe type PChar
begin
Str := 'Latina;0';
Line := TStringList.Create;
try
  ptest := PChar(Str); // // console: warning Unsafe type PAnsiChar
  ExtractStrings([';'],[],PChar(Str),Line);
  finally
  Line.Free;
end;
end;


Viz comment, funkce vrací typ PAnsiChar

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220575

Ano, mám to zobrazené v kukátku a krokuju to v debugeru.

      begin;
        readln(f,line);
        TestFolderInfo.clear;
        try
          ExtractStrings([';'], [], PChar(line), TestFolderInfo);
          if (line='') or ( (line[1]='0') and (trim(line)='0;' ) ) then
            begin
              SubMenuItemsLoaded[pos] := false;
              JazykyFolders[pos] := '';
              JazykySelected[pos] := '';
              continue;
            end;
          pos := JazykyIndexy.IndexOf(TestFolderInfo[0]);
          if pos<>-1 then
            begin
              SubMenuItemsLoaded[pos] := true;
              JazykyFolders[pos] := TestFolderInfo[0];
              if not (DirectoryExists(TestyDir+'\'+JazykyFolders[pos])) then
                 begin
                   CreateDir(TestyDir+'\'+JazykyFolders[pos]);
                   showmessage('Adresář jsem zkusil vytvořit automaticky: '+TestyDir+'\'+JazykyFolders[pos]);
                   ; JazykyFolders[pos] := '';
                   SubMenuItemsLoaded[pos] := false;
                 end
              else
              try
                c := c-1; // potvrdit, že složka s jazykem byla asociována
                JazykySelected[pos] := TestFolderInfo[2];
                if TestFolderInfo[2]='0' then
                  JazykySelected[pos] := ''
                else
                  if not (DirectoryExists(TestyDir+'\'+JazykyFolders[pos]+'\'+JazykySelected[pos])) then
                     begin
                     showmessage('Cesta testu nenalezena: '+TestyDir+'\'+JazykyFolders[pos]+'\'+JazykySelected[pos]);
                     JazykySelected[pos] := '';
                     end;
              except
                JazykySelected[pos] := '';
              end;

            end
          else
            begin // adresář není specifikován
              JazykyFolders[pos] := '';
              SubMenuItemsLoaded[pos] := false
            end;
        finally
        end;
Delphi › Otevření obrázku ze souboru
1. 5. 2018   #220574

Ještě k obrázku dotaz. Když bych ho otevřel (načetl) a chtěl bych s ním dál pracovat, například ho oříznout, nebo zkopírovat jeho část, nebo projít ho a analyzovat barvy, jak se s tím dál pracuje?  Musím nejdříve vytvořit bitmapu TBitmap a do ní nějak zkopírovat data z toho TImage abych s tím mohl pracovat? Jinak jsem to pochopil tak že TImage pouze načte obrázek a umožní ho zobrazit.

Delphi › Otevření obrázku ze souboru
1. 5. 2018   #220572

Lol, tak ona tam ta nápověda je, jenže mě nenapadlo ji použít, jak jsem zvyklý vždy hledat nápovědu online.

Zdá se to být to samé. Jednodušší hledání určitě přes ten program. Jak jsem se dotázal v novém vlákně, tak jsem nepochopil ten 4. argument Strings: TStrings, protože mě se to pole nevyplní daty.

Delphi › ExtractStrings a TStrings
1. 5. 2018   #220570
  1. Připojen obrázek. Proč je pole TestFolderInfo prázdné? Očekával bych dvě položky: Latina a 0

    var TestFolderInfo: TStrings;    
    procedure ...
    begin
    TestFolderInfo := TStringList.Create;
    for i:=0 to maxTestFolders-1 do
     begin;
       readln(f,line);
       TestFolderInfo.clear;
       try
         ExtractStrings([';'], [], PChar(line), TestFolderInfo);
       finally
       end;
    end; end;

Delphi › Otevření obrázku ze souboru
1. 5. 2018   #220569

#4 gna
Nepochopil jsem jak ta nápověda funguje a kde hledat. Hledám teď např. funkci

ExtractStrings a google mi našel "

Search Results System.Classes.ExtractStrings - RAD Studio API Documentation"

adresa:

docwiki.embarcadero.com/Libraries/Tokyo/en/System.Classes.ExtractStrings

Což se mi nezdá že by bylo to co hledám. Používám Borland Delphi personal, nevím co je to RAD Studio.

Delphi › Otevření obrázku ze souboru
30. 4. 2018   #220567

#2 Sniper

A šlo by to udělat i tak, že bych tam ten obrázek vložil? Tedy abych nemusel nic ukládat do resources. Nebo ten TImage pracuje jen s .rc?

Taky dotaz z jakých stránek mám brát oficiální nápovědu pro delphi?

oksi
Delphi › Otevření obrázku ze souboru
30. 4. 2018   #220565

Začínám s Delphi a mám nainstalovanáno Delphi 7 a aplikaci win32 (okna)... A mám takový dotaz. Dejme tomu, že do aplikace dám obrázek, a po otevření (textového)  souboru, kdy z toho souboru načtu adresu obrázku, chci aby se mi ten obrázek co tam je aktualizoval jiným obrázkem. Prostě mi nejde o to aby ten obrázek byl fixní součástí programu, ale aby se dal dynamicky otevřít. Neptám se na to jak načíst soubor txt nebo jak otevřít či zobrazit obraz, pomocí dialogového okna.. Ptám se co potřebuju znát nebo udělat, abych mohl nějaký obrázek otevřít, respektive zobrazit. Týká se to programu na výuku jazyků (který jsem nenapsal, ale chtěl bych ho doplnit o novou funkci) a já bych chtěl zobrazit slovíčko v grafickém provedení v panelu7:TPanel. Poté co bude odpověď zodpovězena je třeba zase obrázek odstranit (refresh) a třeba dát  tam jiný obrázek (opět refresh). Jak se tyto věci dělají?

Visual Basic › Jak zjistit délku dokumentu…
27. 8. 2017   #217679

Jak zjistit jak dlouhý je text v dokumentu (bez použití select all , copy)

Visual Basic › Vložení textu ze schránky
24. 8. 2017   #217633

Tak pořád to dělá tu chybu, jenže ne vždy. Ve schránce údajně data jsou, ale když se debugger zastaví kvůli chybě a přeruším chod makra, tak data ze schránky nejdou vložit (ručně ctrl+v)...

Visual Basic › Vložení textu ze schránky
24. 8. 2017   #217630

Zjistil jsem, že se mi otevírá přinejmenším jedno nové Okno navíc. Po odstranění

Documents.Add DocumentType:=wdNewBlankDocument
se problém vyřešil. Přišel jsem na to že druhý řádek vytváří nový dokument. Tím se asi zpomalila akce pastu a nějak to prostě selhalo.

 

Visual Basic › Vložení textu ze schránky
23. 8. 2017   #217629

V prohlížeči zkopíruju text pomocí jednoho programu, pak spustím makro ve Wordu:

 Documents.Add DocumentType:=wdNewBlankDocument
 Documents.Add.Content.Paste
 Selection.HomeKey Unit:=wdStory


Které má založit nový dokument a vložit tam text ze schránky. Na řádku


Documents.Add.Content.Paste

se mi ale debuger zastaví s chybou. Tak jsem chtěl vědět čím to může nastat.

Těsně předtím spuštěním makra jsem ale kontroloval v externím programu že ty data ve schránce jsou.

Teď se mi to ale zrovna rozjelo, tak číslo chyby nemohu opsat. Dám vědět jestli se to bude opakovat.

Tak chyba kterou to hlásí je 4198, příkaz nebyl úspěšný.

Čím by to mohlo být?

Deď jsem překontroloval co je ve schránce pomocí VBA a text tam je.

 Documents.Add DocumentType:=wdNewBlankDocument
 
 Dim BufObj As MSForms.DataObject, BufTxt As String
 Set BufObj = New MSForms.DataObject
 BufObj.GetFromClipboard
 BufTxt = BufObj.GetText

 Documents.Add.Content.Paste
 Selection.HomeKey Unit:=wdStory
Visual Basic › Makro pro Word: Jak zjistit…
22. 8. 2017   #217609

Zajímavé, tak jsem to našel pod Windows/system32

Dík

Visual Basic › Makro pro Word: Jak zjistit…
22. 8. 2017   #217607
Visual Basic › Makro pro Word: Jak zjistit…
22. 8. 2017   #217603

Jsem rád, že tady existuje tahle diskuse. Zrovna se snažím přijít na to jak rozjet tento kód:

Sub isTextSelected_()
    ' Is text selected?

    InSelection = False
    If Selection.Type = wdSelectionIP Then InSelection = True

    ' Clear Clipboard
    If InSelection = False Then
        Dim MyData As DataObject
        Set MyData = New DataObject
        MyData.SetText ""
        MyData.PutInClipboard
    Else
        Selection.Copy
        Documents.Add.Content.Paste
    End If
End Sub

Který jsem odvodil z jisté webové stránky. Kde se píše:

The DataObject object is a part of the Forms library in VBA. In order to make this code work, you must do one of two things.

Have at least one UserForm in your project, or
In the VBA editor, go to Tools, References, and set a reference to the "Microsoft Forms 2.0 Object Library"

 

Myslím že první část kde se ptám jestli je text vybrán funguje.

Teď ale potřebuju vyřešit jak DataObject. Mám čistý dokument do kterého vložím tabulku z netu. Tu pak procházím a kopíruju z ní text. Občas ale nastane situace, že text není vybraný a nelze do něj nic zkopírovat. Já tedy potřebuju vymazat schránku, pokud nic není vybráno; a nastavit schránku na to co je vybráno pokud je výběr uskutečněn.

C / C++ › Jak otevřít soubor v C++ a n…
20. 8. 2017   #217590

Jo, dík, ale už to mám hotové. Tedy udělal jsem to trochu jinak, ale i tak se tvůj kód bude hodit v budoucnu.

C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217587

#10 oxidián
Chybu jsem odstranil a teď se snažím přijít na to jak udělat toto:

found = line.find(':',3);

potřebuju vrátit řetězec, který začíná za dvojtečkou a končí před mezerou

např:101 // tady je už koment
C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217582

Nevím čím to je, ale pořád mi to krachuje.

          std::string line;
          while ( ifs.good() )
             {
             getline (ifs, line);
             if ( line.length() == 0) {
                 c++;
                 cStr << c;
                 line = line + "<h3>"  + cStr.str() + "<h3>";
                 }

             std::cout << line << std::endl;

             // 1.
             boost::replace_all(line, "abc", "hij");
             boost::replace_all(line, "def", "klm");

             // 2.
             line = boost::replace_all_copy (
             boost::replace_all_copy<string>
                  ("abc def abc def", "abc", "hij")
                  ,  "def"
                  ,  "klm"
                );

              } // end while


Snažím se o to, že pokud je řádek prázdný, chci změnit řádek na nadpis s číslem prázdného řádku.

C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217580

#4 gna

To není možný že by to nešlo jednoduše po řádkách. Ten soubor se přece může zapsat jako nový do jiného adresáře.

C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217579

verze stringstream jede 9x pomaleji

C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217578

Druhá možnost, ale zdá se že jede mnohem pomaleji než ten první, kde jsem pracoval po řádcích:

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <dirent.h>
using namespace std;

int main () {
  std::string line;
  std::stringstream stream;
  std::string content;
  std::string path = "U:\\C\\NBK\\txt";
  DIR *dir;
  struct dirent *ent;

  if ((dir = opendir (path.c_str() )) != NULL) {
      while ((ent = readdir (dir)) != NULL) {
        printf ("%s\n", ent->d_name);
        std::string tmp = path + "\\" + ent->d_name;
        ifstream ifs( tmp.c_str() );
        if (ifs.is_open())
          {
            /*
            while ( ifs.good() ) {
              getline (ifs, line);
              cout << line << endl;
            } */
            stream << ifs.rdbuf();//read the file
            std::string content = stream.str(); //str holds the content of the file
            ifs.close();
            std::cout << content << std::endl;
          }
        else cout << "Unable to open file\n";
      } // end while
      closedir (dir);
    } else {
       perror ("File open failed");
      return 0;
    }


  return 0;
}
C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217577

Mám převést zdroj programu na Windows-1250?

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <dirent.h>
using namespace std;

int main () {
  string line;
  std::string path = "U:\\C\\DIR\\txt";
  DIR *dir;
  struct dirent *ent;

  if ((dir = opendir (path.c_str() )) != NULL) {
      while ((ent = readdir (dir)) != NULL) {
        printf ("%s\n", ent->d_name);
        std::string tmp = path + "\\" + ent->d_name;
        ifstream ifs( tmp.c_str() );
        if (ifs.is_open())
          {
            while ( ifs.good() )
            {
              getline (ifs, line);
              cout << line << endl;
            }
            ifs.close();
          }
        else cout << "Unable to open file\n";
      } // end while
      closedir (dir);
    } else {
       perror ("File open failed");
      return 0;
    }


  return 0;
}

Ono to furt odebírá zpětné lomítka

C / C++ › Jak otevřít soubor v C++ a n…
19. 8. 2017   #217570

   

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <dirent.h>
using namespace std;

int main () {
  string line;

    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir ("U:\\C\\DIR\\TXT")) != NULL) {
      while ((ent = readdir (dir)) != NULL) {
        printf ("%s\n", ent->d_name);
        ifstream ifs( ent->d_name );
        ifs.open (ent->d_name, std::ifstream::in);
        if (ifs.is_open())
          {
            while ( ifs.good() )
            {
              getline (ifs, line);
              cout << line << endl;
            }
            ifs.close();
          }
        else cout << "Unable to open file\n";



      } // end while
      closedir (dir);
    } else {
       perror ("File open failed");
      return 0;
    }


  return 0;
}


Můžete mi říct proč se mi nedaří otevřít soubor? Se souborem chci provést nahrazování po řádcích.

Soubory typu txt, kódování WINDOWS-1250, obsahují české znaky

Např.

A) pokud řádek obsahuje string (hledání pomocí regulárního výrazu), pak ho pak přidej <stroke>...text řádku..</stroke>

nebo

B) odstraň řádek

nebo

C) nahraď určité slova za jiné slova. Např. Motor\w*, Auto\w* nahraď za stroj. Nebo Motorka nahraď za Motocykl apod.

C / C++ › Funkce na sestavení cesty vr…
18. 8. 2017   #217568

Budu to řešit později. Teď jsem si dal od toho pauzu a budu se muset nad tím opět zamyslet.

Pokud si pamatuju z paměti:

MSB má fungovat takto: 12x cyklus ve kterém provádím 2x kopírování a posun. Celkem se uloží 2x12 bitů výsledkem má být 24 bitů čili 3 byty.

LSB má mít zbývajících 12x16 bytů.

Jinými slovy jsem rozdělil 18 bytů x 12 na (2+16) * 12.

C / C++ › Funkce na sestavení cesty vr…
15. 8. 2017   #217496

vracet [] přece nejde, tak jsem tam nechal pointer; nevěděl jsem co s tím

Tak jo, to vynulování funguje, takže jsem úspěšně odbugoval první fázi programu.

C / C++ › Funkce na sestavení cesty vr…
15. 8. 2017   #217493

Ono by to chtělo vynulovat celý ten struct

TABLES tables;

mohu na to použít

void * memset ( void * ptr, int value, size_t num );

memset ( &tables, 0, sizeof(tables) ); ???

C / C++ › Funkce na sestavení cesty vr…
15. 8. 2017   #217487

Kód té funkce po odstranění komentářů.

char * prepareFilePath(TABLE_ tmain, TABLE_ tob, char filename[])
{
    if ( strlen (tob.submain_directory))
        sprintf(filename, "db/%s/%s/%s", tmain.main_directory,tob.submain_directory,tob.filename );
    else
        sprintf(filename, "db/%s/%s/%s", tmain.main_directory,tmain.submain_directory,tob.filename );
  return filename; // zde je hodnota filename správně
}

Už jsem na to přišel. Tak problém byl někde jinde.

tob.submain_directory není vynulovaný a je v něm hodnota \"\000

V důsledku toho mi nevýjde test strlen (tob.submain_directory)
.

C / C++ › Funkce na sestavení cesty vr…
15. 8. 2017   #217486

header

https://paste.ofcode.org/3GmzmFCjfbg4uHtJfr7YvX

c file:

https://paste.ofcode.org/dXCRVU8jEL2yYfKPhHAYUt

Nekopíruju adresářovou strukturu db, takže jestli mi s tím chceš pomoci, na řádku 146 funkce readfile bude vždy vracet null pointer.

Nicméně já mám debugger nastavený takto:

breakpoint na řádku 118: ve funkci prepareFilePath, větev else.

breakpoint na řádku 150.

Když se to zastaví na řádku 150 hodnota filename je

db/radiation/insolation incident/\"/maximum direct radiation.txt

ale předtím ještě před vrácením filename, na řádku 118, respektive na 127 byl filename správně

db/radiation/insolation incident/July 1983 - June 2005/insolation - clear sky - horizontal surface.txt

Funkci char * prepareFilePath(TABLE_ tmain, TABLE_ tob, char filename[])

jsem původně měl deklarovanou takto:

char * prepareFilePath(TABLE_ tmain, TABLE_ tob, char * filename) ...

Jenže filename je pole char:

char * prepareBuffer(TABLES * tables, char * buf, TABLE_ * table_arrays[]){
    char filename[400];

takže jsem to opravil

char * prepareFilePath(TABLE_ tmain, TABLE_ tob, char filename[])


Nicméně to nemá vliv, program se chová stále stejně. Několik cest mi prošlo bez problému, a tady u této to dělá problém.cesta se skládá ze řádku

5 (hlavní adresář), 14 (podadresář), 6 (druhý soubor)

C / C++ › nastavení pointeru
14. 8. 2017   #217479

Mě to hlásilo trochu jinou hlášku a neměl jsem tam anonymní struct.

C / C++ › nastavení pointeru
14. 8. 2017   #217473

Kompilátor do toho upozornění rovnou dává doporučení jak by to mělo vypadat?


test.c:75:35: warning: passing
argument 3 of ‘prepareBuffer’ from incompatible pointer type [-Wincompatible-pointer-types]
     prepareBuffer(tables, rowBuf, table_arrays);
 

C / C++ › nastavení pointeru
13. 8. 2017   #217463

#26 KIIV
Na tento příspěvek jsem zapomněl. Takže teď vidím kde jsem udělal ty chyby:

V main jsem deklaroval:

TABLES tables;
TABLE_ *table_arrays[6]; // pointer na pole typu TABLE_

ale v readfiles jsem deklaroval

void readfiles(TABLES * tables, TABLE_ * table_arrays) // pointer na strukturu typu TABLE_ nebo dokonce TABLES

a v prepareBuffer to samé.

Myslím tedy že toto si už budu pamatovat:

char * prepareBuffer(TABLES * tables, char * buf, TABLE_ * table_arrays[];

void readfiles(TABLES * tables, TABLE_ * table_arrays[]);

Toto:

for(i = 0; i<TABLE_TYPES_NUM; i++) // count of tables
    {
    TABLE_ * table_item = &(table_arrays[i]);
    currentTableElementsNum = (table_item[0]).num;
    printf("%d => %d\n", i, currentTableElementsNum);
    }

Na 3. řádku mělo být:

TABLE_ * table_item = table_arrays[i];
 

Tedy hlavní problém byl v té deklaraci typů v hlavičkách funkcí.

Ta šílenost v tom cyklu, nebyla až tak podstatná, protože jsem to table_arrays[i] testoval v kukátku. Podstatná chyba byl ten pointer na typ TABLE_ nebo TABLES a tím pádem jsem se nemohl dostat dál.

Dík za vyřešení.

C / C++ › nastavení pointeru
13. 8. 2017   #217460

Přesně, ale mě to nevypisuje tak jak tobě. Mě to vypisuje 0 => 2289584. Nevím proč

C / C++ › nastavení pointeru
13. 8. 2017   #217458

#25 BDS
Tak jistě, KIIV po mě chtěl minimální zkompilovatelný kód.

Pravda, to nastavení pointerů na jednotlivé členy tables bude lépe přesunout za initiate.

#26 KIIV
Zapomněl jsem uvést, že jde o tento řádek

currentTableElementsNum = (table_item[0]).num;


Kde vložíš breakpoint. Po prvním zastavení, až zpracuješ ten řádek

table_item[0] má obsahovat ty hodnoty, které byly iniciovány, konkrétně jsem inicioval

tables->radiation_insolation[0].num = 7;

takže (table_item[0]).num by mělo vrátit 7.
 

C / C++ › nastavení pointeru
13. 8. 2017   #217451

#20 KIIV

Dalo napsat přímo. To jsem tam měl ne? Původně jsem tam měl:

TABLES * table_types[TABLE_TYPES_NUM]; // 6table_arrays[0] = tables.radiation_insolation;
table_arrays[1] = tables.radiation_radiation;
table_arrays[2] = tables.winds;
table_arrays[3] = tables.pressure;
table_arrays[4] = tables.humidity;
table_arrays[5] = tables.temperature;

Pak nevím proč to Jerry přepisoval. Myslel jsem že to mám špatně.

edit:

Nesedí mi tam ty adresy:

očekávám že ve funkci initiate se table_arrays.radiation_insolation[0].num nastaví na 7

ale hodnota je 2289584...

To znamená, že table_arrays[0] neodkazuje na adresu tables.radiation_insolation. ... &table_arrays odkazuje na (TABLES *) 0x22ea14 ... ale &tables->radiation_insolation odkazuje na (TABLE_ ()[7]) 0x22ea38 ...

a

&(table_arrays)[0] odkazuje na (TABLES *) 0x22ea20.

takže mi to nesedí.

C / C++ › nastavení pointeru
13. 8. 2017   #217449

#18 BDS
Jestli ti jde o to že používám funkci initiate, tak tu používám už od samého začátku, jen jsem ji sem neuváděl. Kód o 106 řádcích by nikoho nezajímal.

C / C++ › nastavení pointeru
13. 8. 2017   #217447

#11 Jerry

napsal si

tableTypes[0] = &(tables.radiation_insolation[0]);

Akorád, že já potřebuju toto:

tableTypes[0] = &(tables.radiation_insolation);

Mně víc vyhovuje psát místo tableTypes table_arrays.

Ke členu num bych tedy měl přistupovat takto:

table_arrays[0][0].num

nebo table_arrays[i][j].num

Teď zkouším toto:

table_arrays[0] = &(tables.radiation_insolation);

TABLE_ test_tab = table_arrays[0][0];

test_tab.num = 999;
initiate(&tables, &test_tab);

...

void initiate(TABLES * tables, TABLE_ * test_tab){

tables->radiation_insolation[0].num = 7;

// tady mám break point a podívám se do kukátka na test_tab.num

V kukátku bych měl vidět test_tab: 7, ale vidím 999

ještě uvažuju nad tím proč to funguje jinak než bych očekával. Zkoušel jsem to do té funkce dostat i jako
TABLE_ test_tab, ale výsledek je stejný.
 

C / C++ › nastavení pointeru
8. 8. 2017   #217380

#10 KIIV
Použil jsem google abych si vyhledal něco o statických polích a vypadlo mi toto:

Static arrays are allocated memory at compile time and the memory is allocated on the stack. Whereas, the dynamic arrays are allocated memory at the runtime and the memory is allocated from heap.

Ale v komentářích jsem našel nějaké rozpory. Je ta věta pravdivá nebo pomýlená?

C / C++ › nastavení pointeru
8. 8. 2017   #217376

#6 Jerry
Vyrostl jsem na PHP 3-4, v menší míře Javascript a JQuery. Později jsem se věnoval AHK. V posledních letech jsem se věnoval kromě programování v jiných jazycích i programu Sketchup na čemž jsem strávil měsíce. Tudíž není pravda co si o mě hu myslí, že jsem veškerý čas tří let věnoval jenom C/C++.

C / C++ › nastavení pointeru
8. 8. 2017   #217375

#5 gna
Pochopil jsem to že jsem to špatně deklaroval. Ta proměnná byla něco jiného než jsem si myslel.

Teď se už ale zaměřuji na jiné řešení.

1) přejmenoval jsem tu proměnnou aby se mi to nepletlo

2) pochopil jsem to že potřebuji pointer to arrays of array of type TABLE_

ale dávat tam typ TABLE_ ** by znamenalo alokovat paměť a nevypadá to jako dobré řešení.

Nyní mám toto:

    TABLE_ *table_arrays[] = {
    tables.radiation_insolation,
    tables.radiation_radiation,
    tables.winds,
    tables.pressure,
    tables.humidity,
    tables.temperature
};

A z toho budu vycházet.

C / C++ › nastavení pointeru
8. 8. 2017   #217372

#2 hlucheucho
1. table_types je pole struktur. O několik řádků níž plníš jednotlivé prvky ( = struktury) položkami struktur.

typedef struct {
    TABLE_ radiation_insolation[7];
    TABLE_ radiation_radiation[5];
    TABLE_ winds[9];
    TABLE_ pressure[1];
    TABLE_ humidity[1];
    TABLE_ temperature[4];
} TABLES;

Tak já předpokládal, že každá položka má jinou velikost (rozměr pole je 7, pak 5, pak 9, pak 1, 1 a nakonec 4 ),

Pokud by to ale byly pointery na pole tak by bylo jasné že velikost celého typu TABLES by byla 6*sizeof(int) a nebylo by co řešit.

2) i=0 je začátek cyklu. V cyklu budou funkce.
3) "V době překladu je známa velikost pole daná makrem
TABLE_TYPES_NUM,"

A k čemu mi to je dobré, když velikost každé položky (členu struktury TABLES tables) je jiná?

C / C++ › nastavení pointeru
8. 8. 2017   #217369

Mám tyto dvě struktury:

typedef struct {
    int skip_lines;
    int num;
    int i;correctly and then not to change!
    char filename[70];
    char main_directory[16];
    char submain_directory[100];
} TABLE_;

typedef struct {
    TABLE_ radiation_insolation[7];
    TABLE_ radiation_radiation[5];
    TABLE_ winds[9];
    TABLE_ pressure[1];
    TABLE_ humidity[1];
    TABLE_ temperature[4];
} TABLES;

ve funkci main dělám toto:

TABLES tables;
TABLES * table_types[TABLE_TYPES_NUM]; // 6 - count of table types
table_types[0] = tables.radiation_insolation;
// int si = sizeof( *(table_types[0]) ); // insolation size 5400 checked
table_types[1] = tables.radiation_radiation;
table_types[2] = tables.winds;
table_types[3] = tables.pressure;
table_types[4] = tables.humidity;
table_types[5] = tables.temperature;
initiate(&tables);
readfiles(&tables, table_types);

radiation_insolation je pole typu TABLE_ o rozměru 7. funkce initiate načte data ze souboru do 7 tabulek typu radiation_insolation. Pak spouštím funkci readfiles, respektive preaparBuffer kde řeším následující věc:
 

prepareBuffer(&tables, rowBuf, table_types);
char * prepareBuffer(TABLES * tables, char * buf, TABLES * table_types);
    TABLE_ * t;
    int currentTableElementsNum = 0;
    int offset = 0;
    // iterrate through table types.
    t = &(table_types[i]);
    for(i = 0; i<TABLE_TYPES_NUM; i++) // count of tables
        {
        t += offset;
        offset += sizeof(table_types[i]);
        }

V prvním cyklu t je (TABLE_ *) 0x22ea20

offset je 5400, což se shoduje s testem velikosti, který jsem dělal přímo v main().

V druhém cyklu chci nastavit ukazatel na následující pole tabulek, kterým je
radiation_radiation o rozsahu 5.

Myslel jsem si že pozice na následující pole tabulek se vypočítá takto:


offset += sizeof(table_types[i]);
t += offset; // nastavit pointer t + offset
no, ale v druhém cyklu dostávám že t ukazuje na nepřístupnou část paměti 0x3364e0.

Podle mých výpočtů by adresa měla být

t: 0x22ea20 + 5400 dec čili (0x22ea20  + 0x1518) = **0x22FF38**

Kde tedy dělám chybu, že to neukazuje správně na druhou sadu tabulek?

C / C++ › zkopírování části paměti - m…
8. 8. 2017   #217367

Jsou to tvoje pochyby ne moje. Za dobu co jsem chodím jsem se věnoval třem, respektive čtyřem jazykům. Céčko jsem skoro úplně zapomněl, takže je to jako bych začal právě teď.  Ale neboj já si zase rozpomenu.

C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217360

Radši ne. Dík. Já se to kdysi učil, ale paměť to víš, časem se to vykouří jak to člověk málo používá nebo nepoužívá.

C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217358

A tak jo, já jsem se to kdysi učil ty různé soustavy a rozebírání čísel. Myslím že jsem to ještě nezapomněl.

C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217356

#9 KIIV
"m[i+1] & 0xFFFFu; // urcite neprepise nic nad 16. bit, jelikoz se tam nemuze vyskytnout zadna logicka jednicka"

OK. To dává smysl. Takže když říkáš "nad 16. bit" to tedy v programátorské hantýrce znamená směrem od LSB k MSB, chápu to správně?

C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217354

unsigned int m[12];

unsigned int LSB = 0;

Tak asi to má být takto:

LSB = 0;
LSB |= m[i] & 0xFFFFU << 16; // 16 bits LSB
LSB |= m[i+1] & 0xFFFFU;

A hle, ono to funguje! Tak dík.

Druhý řádek nastaví LSB: 196608

třetí řádek LSB: 196611

A dále v kódu pak s je:

s[0] = 3 '\003'

s[1] = 0 '\000'

s[2] = 3 '\003'

s[3] = 0 '\000'
C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217352

Ještě potřebuju vyřešit jednu věc s tím LSB,

m[i] = 0b000000110000000000000011; // 196609

m[i+1] = 0b000000110000000000000011; // 196609
LSB = 0;
LSB |= m[i] & ~0xFFFF0000 << 16; // 16 bits LSB
LSB <<= 16;
LSB |= m[i+1] & ~0xFFFF0000; // tady se má zkopírovat jen 2 byty zprava, aby se nepřepsalo to co jsem zkopíroval a posunul výše.

Jak opravit ten poslední řádek aby se zkopírovaly jen 2 byty neboli 16bitů? Jde o to zachovat 16 bitů MSB a zkopírovat tam 16 bitů zprava.

Pro tom prvním posunu se z čísla 3 stane binárně

11000000 00000000 00

a po druhém nakopírování by tam mělo být

11000000 00000000 11

teda správně rozděleno by to bylo takto:

   |-> dalších 16 bitů

11 00000000 00000000

11 00000000 00000011
C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217351

Já už vím co mám špatně (částečně). Já nemám pracovat přímo s buf ale s pointerem s ukazujícím na buf

char * s, *pEnd, *pStart, *pMSB2start, *pLSB16start;
pEnd = buf + bufLen - 1; // pEnd is +1B out of buffer!
pMSB2start = pEnd;
pLSB16start = pEnd - 3; // -3B ; 2b * 12 = 24b = 3B
s = pLSB16start;

...

s -= 4; // set pointer

memcpy(s, &LSB, 4);

s before: 0x22e864 "Aenean."

s after: 0x22e864 "�03"

// s: 0x22e864 "Aenean."
s[0] = LSB << 24;
s[1] = LSB << 16;
s[2] = LSB << 8;
s[3] = LSB;

můj výsledek:

s[0] = \000

s[1] = \000

s[2] = \000

s[2] = \003

což vypadá že se někam vytratili ty dvě binární 11 na začátku (zleva) LSB

tak asi ten kod není dobře

ale toto funguje:

*((unsigned int*)s) = LSB;


výsledek:

3 '\003'
0 '\000'
3 '\003'
0 '\000'
C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217349

Operace mecpy ale ani nevymaže ty data, takže se nekopíruje nic. Ten původní řetězec zůstal nedotčený.
 

Ani toto nedělá změnu:

buf[0] |= LSB & 0xFF000000 ;
buf[1] |= LSB & 0x00FF0000 << 8;
buf[2] |= LSB & 0x0000FF00 << 16;
buf[3] |= LSB & 0x000000FF << 24;
C / C++ › zkopírování části paměti - m…
7. 8. 2017   #217347


LSB je int. buf je char *. Potřebuji do buf nakopírovat 4 byty z LSB (z leva doprava). Zkouším dvě možnosti:
 

1)
buf[0] |= LSB & 0xFF000000;
buf[1] |= LSB & 0x00FF0000;
buf[2] |= LSB & 0x0000FF00;
buf[3] |= LSB & 0x000000FF;
nic to nedělá
2)
memcpy(buf, (int) &LSB, 4); // přepiš 3 byty od konce

taky nic to nedělá


buf: 0x22e864 "Aenean."

LSB: 196611


Když vymažu operátor & u memcopy tak mám hlášení: makes pointer from integer without a cast [enabled by default]| include\string.h|38|note: expected 'const void *' but argument is of type 'int'| Přímo LSB jako source tam dát nemohu, to by krachlo. Co s tím?
 

C / C++ › Pointer na char array
6. 8. 2017   #217337

#2 gna
Díky moc

C / C++ › Pointer na char array
6. 8. 2017   #217335

Řádek 3:  pEnd = buf;
Warning: assignment makes integer from pointer without a cast

int readfile(char * name, int skip, char * buf, int bufLen, int shift ){
    char * s, pEnd, pStart, pMSB2start, pLSB16start;
    pEnd = buf;

...}

void readfiles(FILES * files){
    char filename[400];
    char rowBuf [ROW_LENGHT];
    memset ( rowBuf, 0, ROW_LENGHT );
...
readfile(filename, 14, rowBuf, bufLen, shift);
}

Alternativně pokus:

pEnd = *buf;

přidám tam breakpoint a kukátko

buf: 0x22e58f "<p>Lorem ipsum dolor sit amet ... na ."

60 '<' ....

Potřebuji nastavit pEnd na stejnou adresu. Zkoušel jsem

pEnd = &buf;

a taky nic.

Vypadá to že hádám, ale stránku o pointerech (cplusplus tutorial) jsem si znovu přečetl a zas nechápu kde je chyba. Já myslel že když dám pEnd = buf tak to bude ukazovat na stejnou adresu.

C / C++ › unsigned char
6. 8. 2017   #217334

#4 hlucheucho
To jsem nějak přehlédl.

C / C++ › Vymazání bitů
6. 8. 2017   #217332

#3 hlucheucho
Int. Vnulování čísla. Leč uznávám že lepší bude dát tam LSB = 0;

C / C++ › Vymazání bitů
6. 8. 2017   #217331

#2 gna
To se nezdá jak taková maličkost dokáže ovlivnit celý program :-) Dík

C / C++ › Vymazání bitů
6. 8. 2017   #217328

V následujícím kódu jsem na test nastavil hodnotu čísla na 196611.

Nyní chci vymazat první dva byty, respektive, mi stačí vymazat bit 17 a 18 zleva.

Jsou to ty dvě jedničky zastupující číslo 196608.

Když provedu LSB |= m[i] && ~0xFFFF0000;

tak LSB má být 3 a dostávám 1.

for (i = 0; i<11; )
       {
       /////////////////000000001111111100000000
       m[i] = 0b000000110000000000000011; // 196611
       m[i+1] = 0b000000110000000000000011; // 196611
       LSB <<= 32;
       LSB |= m[i] && ~0xFFFF0000; // 16 bits LSB
       LSB <<= 16;
       LSB |= m[i+1] && ~0xFFFF;
       i += 2;
       }

Co dělám špatně?

C / C++ › unsigned char
6. 8. 2017   #217325

#2 gna
Ok, tak to bude nejlepší. Díky

C / C++ › unsigned char
6. 8. 2017   #217321

Jak vyřešit tento problém?

unsigned char rowBuf [ROW_LENGHT];
memset ( rowBuf, 0, sizeof(rowBuf) );

186|warning: pointer targets in passing argument 1 of 'strcat' differ in signedness [-Wpointer-sign]|

mingw\bin\..\lib\gcc\mingw32\4.7.1\..\..\..\..\include\string.h|41|note: expected 'char *' but argument is of type 'unsigned char *'|

mám použít

char rowBuf [ROW_LENGHT];

?

a jaký je tam vlastně rozdíl mezi char a unsigned char? může vůbec char být unsigned? char je rozsah 0-255 tam přece není znaménko...

C / C++ › Dá se bitový posun použít na…
6. 8. 2017   #217319

#23 MilanL
Další možnost, která mě napadla:

rozdělit těch 12 cyklů na 3 cykly. V každém cyklu proběhne toto:

1. do proměnné number typu long double (tj. 10 bytů) zkopíruju 4 čísla tak, že tam pošlu

18 bitů, shift, dalších 18 bitů, shift, dalších 18 bitů, shift, dalších 18 bitů.

Ve výsledku bych pokryl 72 bitů, tj 9 bytů.

2. z proměnné number zkopíruju 9 bytů do buf.

To celé se opakuje třikrát.

Edit:

Akorád je problém že mi to nejde zkopírovat:

    number |= m[i];
    number = m[i] << 18.0l;

dostávám chyby:

error: invalid operands to binary | (have 'long double' and 'long double')|
error: invalid operands to binary << (have 'long double' and 'long double')|

C / C++ › Dá se bitový posun použít na…
5. 8. 2017   #217312

#27 MilanL
No právě že to chci dělat nejdříve po jednom řádku, ne vše 600000 nebo kolik jich je. Jen mám teď problém zase začít po pauze a v těch vedrech se mi nic nechce dělat.

 

 

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