Recent

Author Topic: [SOLVED]Pointeur to string on loop equivalent to C  (Read 1155 times)

andromeda

  • New Member
  • *
  • Posts: 12
[SOLVED]Pointeur to string on loop equivalent to C
« on: November 24, 2020, 10:05:29 pm »
It's been a whole day that I am on this problem that I can not find. I should do the equivalent of the code c below with lazarus:

on C, s is a pointer to char (char *s;), menu is array of string. this code work on C

Code: Pascal  [Select][+][-]
  1. s = 0;
  2.  for (j=0;j<width;j++) {
  3.  if (s && *s)
  4.      _putch(*s++);
  5.  else _putch(' ');
  6.        if (s == 0)
  7.           s = menu[i];
  8.       }
  9.  
  10.  

on lazarus i have tested all possiblity but it don'work. s is declared as s: PAnsiString;
Code: Pascal  [Select][+][-]
  1.  s := nil;
  2.       j := 0;
  3.       while (j < width) do
  4.       begin
  5.         if (s <> nil) and (s^ <> '')  then
  6.            _putch(Byte(s^[j]))
  7.         else _putch(SPACE);
  8.  
  9.         if (s = nil) then
  10.           s := @menu[i];
  11.         j := j + 1;
  12.       end;      
  13.  

for information :
Code: Pascal  [Select][+][-]
  1. procedure _putch(data : byte);
  2. begin
  3.      ser.SendByte(data);
  4.      while(not uartWriteFinished) do ;
  5. end;
  6.  

my probleme is this line:
Code: Pascal  [Select][+][-]
  1.  if (s && *s)
  2.      _putch(*s++);
  3.  
i want to do equivalent on lazarus pascal.
« Last Edit: November 26, 2020, 07:21:57 am by andromeda »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Pointeur to string on loop equivalent to C
« Reply #1 on: November 24, 2020, 10:10:35 pm »

Quote
s && *s

this is something like

Code: Pascal  [Select][+][-]
  1. if assigned(s) and (s^<>#0) then

I also think your s:=@menu is wrong. C doesn't use & there, so I would guess it is a pointer assignment, not an address-of. But without declarations of menu that is only guesswork.

Frankly, that C code seems like a mess.

andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #2 on: November 24, 2020, 10:19:05 pm »
on c, && is equivalent to and

declaration of menu in c is:
Code: Pascal  [Select][+][-]
  1. const static char *mainmenu[] =
  2. {
  3.   "Memory viewer",
  4.   "Console debug demo",
  5.   "Speed test",
  6.   "Test sub menu",
  7.   "Command line interface",
  8.   "ASCII-Art test",
  9.   "Input dialog test",
  10.   0
  11. };
  12.  

declaration of menu on pascal is:
Code: Pascal  [Select][+][-]
  1.  mainmenu : array of string = (
  2.   'Memory viewer',
  3.   'Console debug demo',
  4.   'Speed test',
  5.   'Test sub menu',
  6.   'Command line interface',
  7.   'ASCII-Art test',
  8.   'Input dialog test',
  9.   #0);    
  10.  
with your code it don't work, but i think the probleme is here.

Code: Pascal  [Select][+][-]
  1.  if (s = nil) then
  2.           s := @menu[i];  
  3.  
  4.  

how do i do for pointing to string menu index.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Pointeur to string on loop equivalent to C
« Reply #3 on: November 24, 2020, 10:23:37 pm »
It's been a whole day that I am on this problem that I can not find. I should do the equivalent of the code c below with lazarus

Your translation is incorrect.  It should look something more like this instead:

Code: Pascal  [Select][+][-]
  1. menu: array[...] of PAnsiChar; // <-- or AnsiString
  2. i: Integer;
  3.  
  4. ...
  5.  
  6. var
  7.   s: PAnsiChar; // <-- not PAnsiString
  8.   j: Integer;
  9.   ...
  10. begin
  11.   ...
  12.   s := nil;
  13.   for j := 0 to width-1 do
  14.   begin
  15.     if (s <> nil) and (s^ <> #0) then
  16.     begin
  17.       _putch(Byte(s^));
  18.       Inc(s);
  19.     end else
  20.       _putch(Byte(' '));
  21.     if s = nil then
  22.       s := menu[i]; // <-- no @ here
  23.       // or:
  24.       // s := PAnsiChar(menu[i]); // <-- if menu is an array of AnsiString
  25.   end;
  26.   ...
  27. end;
  28.  
« Last Edit: November 24, 2020, 10:27:13 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #4 on: November 24, 2020, 10:58:11 pm »
with my code original i have this.
https://imgur.com/eAxqvxh

if i modify the code:
Code: Pascal  [Select][+][-]
  1. _ if (s <> nil) and (s^ <> '')  then
  2.            _putch(Byte(s^[j]))
  3.  
by
Code: Pascal  [Select][+][-]
  1.  if (s <> nil) and (s^ <> '')  then
  2.            _putch($65)
  3.  

i have this, it work but is not menu item that it displayed
https://imgur.com/hMA1fNe

if i replace the code by code from Remy LeBeau, i have this,it's almost that
https://imgur.com/sXfOYqh

on the code by Remy LeBeau i replaced
Code: Pascal  [Select][+][-]
  1. s := menu[i];
  2. by
  3. s := PAnsiChar(menu[i]);
  4.  
  5.  
else it crash

andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #5 on: November 24, 2020, 11:42:25 pm »
it wotk when i modify number of item of menu

see image: https://imgur.com/lab3iJR

Code: Pascal  [Select][+][-]
  1.  mainmenu : array of PAnsiChar = (
  2.   'Memory viewer',
  3.   'Console debug demo',
  4.   'Speed test',
  5.  // 'Test sub menu',
  6.  // 'Command line interface',
  7.  // 'ASCII-Art test',
  8.  // 'Input dialog test',
  9.   #0);  
  10.  

When i uncomment other item menu it don't work

https://imgur.com/sXfOYqh

may be a problem with a pointer or address

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Pointeur to string on loop equivalent to C
« Reply #6 on: November 25, 2020, 12:07:47 am »
Hi!

Dont try to translate the code from C to Pascal literally.

You did not show us the whole original code, but for such a job,
you don't need even one pointer in Pascal.
In the Pascal syntax.

Pascal syntax goes this way:
empty strings are

Code: Pascal  [Select][+][-]
  1. if s = '' then ..
  2. // or
  3. if length(s) = 0 then ....
  4.  

Tests on #0 are definitly wrong as every Pascal string is allowed to contain a #0 somewhere.
At the front. In the middle. At the end. #0 is treated as every other char.

Show us more of your C code and it seems to be a job of some minutes  to concert it.

Winni



andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #7 on: November 25, 2020, 12:18:49 am »
all workf fine now, the code from Remy Lebeau work,this was another problem with the length of menu items.

@wimi.
if 's' its a pointeur i can test with length ?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Pointeur to string on loop equivalent to C
« Reply #8 on: November 25, 2020, 01:27:35 am »

@wimi.
if 's' its a pointeur i can test with length ?

No!

But one step back.

When Niklas Wirth developed Pascal he wanted his students to learn logic and data flow but not to mix them up with system internal like C does.

So his concept was to hide all the pointers in his language for the simple actions.
It it was unavoidable (starting with linked lists and trees) then pointers are used.

In this state of some simple menu stuff: From the Pascal way there is not one pointer.


Length is used for the length of all kind of string:
Shortstrings, AnsiStrings, WideStrings, RawStrings, UTF8Strings. And Strings.

A special position has the pchar as connector between the OS and Pascal.
As the OS are most written in C (Windows, Linux) you have somehow read the strings from them.

So on the one hand the pchar is some kind of hybrid:
ii is some special kind  of a string. And it is a pointer.


This is legal Pascal:

Code: Pascal  [Select][+][-]
  1. var s: string;
  2.      p:pchar;
  3. ....
  4. s :=  'One';
  5. p := 'Three';
  6. writeln (Length(s)+ ' / ' +length(p) );
  7.  
  8.  

Trapp: Pascal strings start counting at 1
           Pchar starts counting at 0

You can convert one type to the other with:

Code: Pascal  [Select][+][-]
  1. var s: string;
  2.      p:pchar;
  3. ....
  4. p := Pchar(s);
  5. s := p;
  6.  

Not so easy to look at the same problem from the other end of the world ...

Keep on hackin'

Winni

andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #9 on: November 25, 2020, 01:37:26 am »
Thanks for your information.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Pointeur to string on loop equivalent to C
« Reply #10 on: November 25, 2020, 01:57:44 am »
@andromeda, it is really hard to help you when you have only shown pieces of the overall code.  Please provide a complete snippet that people can actually compile and run, and then someone will be able to tell you exactly why it is failing.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #11 on: November 25, 2020, 05:33:40 pm »
Thank you remy , your code it work fine., this code is for microvga, it's a traduction code for Atmega128, pic18f4550 and stm32f103, it work in this MCU that i tested and it work fine.

below a portion of code for menu. (ui.pas)
Code: Pascal  [Select][+][-]
  1. unit ui;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils;
  9.  
  10.  
  11. procedure drawfkeys(x, y: integer; fkeys: array of string);
  12. procedure drawframe(x, y, width, height, color : integer);
  13. function runmenu(x, y : byte; menu : array of PAnsiChar; defaultitem: integer): integer;
  14. procedure drawbox(x, y, width, height, color, border: integer);
  15. procedure drawboxnum(num, x, y, color, border: integer);
  16.  
  17. implementation
  18.  
  19. uses
  20.   gconst, conio, kbd;
  21.  
  22. procedure drawfkeys(x, y: integer; fkeys: array of string);
  23. var
  24.   i, j: integer;
  25.   s: string;
  26. begin
  27.  
  28.   gotoxy(x, y);
  29.   for i := 0 to 9 do
  30.   begin
  31.     textcolor(WHITE);
  32.     textbackground(BLACK);
  33.  
  34.     if (i <> 0) then
  35.       _putch(SPACE);
  36.  
  37.     if (i = 9) then
  38.     begin
  39.       _putch($31);
  40.       _putch($30);
  41.     end
  42.     else  _putch((i mod 10) + $31);
  43.  
  44.     textcolor(BLACK);
  45.     textbackground(CYAN);
  46.  
  47.     if (fkeys[i] <> #0) then
  48.        s := fkeys[i]
  49.     else s := #0;
  50.  
  51.     for j := 0 to 5 do
  52.     begin
  53.       if ((s <> '') and (s[j] <> #0)) then
  54.          _putch(Ord(s[j]))
  55.       else _putch(SPACE);
  56.  
  57.     end;
  58.   end;
  59. end;
  60.  
  61.  
  62. procedure drawframe(x, y, width, height, color : integer);
  63. var
  64.   i, j : integer;
  65. begin
  66.   textattr(color);
  67.   gotoxy(x,y);
  68.  
  69.   _putch(ACS_ULCORNER);
  70.   i := 0;
  71.   while i < (width + 2) do
  72.   begin
  73.       _putch(ACS_HLINE);
  74.       i := i + 1;
  75.   end;
  76.  
  77.   _putch(ACS_URCORNER);
  78.  
  79.   for i := 0 to (height - 1) do
  80.   begin
  81.     gotoxy(x, y + i + 1);
  82.     _putch(ACS_VLINE);
  83.     _putch(SPACE);
  84.  
  85.     for j := 0 to  width - 1 do
  86.         _putch(SPACE);
  87.  
  88.     _putch(SPACE);
  89.     _putch(ACS_VLINE);
  90.   end;
  91.  
  92.   gotoxy(x, y + height +1);
  93.   _putch(ACS_LLCORNER);
  94.  
  95.   i := 0;
  96.   while i < (width + 2) do
  97.   begin
  98.        _putch(ACS_HLINE);
  99.        i := i + 1;
  100.   end;
  101.   _putch(ACS_LRCORNER);
  102. end;
  103.  
  104.  
  105. function runmenu(x, y : byte; menu : array of PAnsiChar; defaultitem: integer): integer;
  106. var
  107.   key : byte;
  108.   i, j,  itemno: integer;
  109.   nitems : integer;
  110.   width: integer;
  111.   s: PAnsiChar;
  112. begin
  113.   itemno := defaultitem-1;
  114.   width := 22;
  115.  
  116.   nitems := 0;
  117.  
  118.   while (menu[nitems] <> '') do
  119.   begin
  120.      j := 0;
  121.     while (menu[nitems][j] <> #0) do Inc(j);
  122.       if (j > width) then
  123.          width := j;
  124.       nitems := nitems + 1;
  125.   end;
  126.   width+=2;
  127.  
  128.   if ((itemno < 0) or (itemno > nitems)) then
  129.     itemno := 0;
  130.  
  131.   while (true) do
  132.   begin
  133.     cursoroff();
  134.     textattr((CYAN << 4) or BLACK);
  135.     gotoxy(x,y);
  136.     _putch(ACS_ULCORNER);
  137.  
  138.     i := 0;
  139.     while( i < (width + 2)) do
  140.     begin
  141.        _putch(ACS_HLINE);
  142.        Inc(i);
  143.     end;
  144.     _putch(ACS_URCORNER);
  145.  
  146.     for i := 0 to (nitems - 1) do
  147.     begin
  148.       gotoxy(x,y+i+1);
  149.       _putch(ACS_VLINE);
  150.       _putch(SPACE);
  151.       if (i = itemno) then
  152.           textattr(YELLOW);
  153.  
  154.       s := nil;
  155.       for j := 0 to (width - 1) do
  156.       begin
  157.         if (s <> nil) and (s^ <> #0)  then
  158.         begin
  159.             _putch(Byte(s^));
  160.             Inc(s);
  161.         end
  162.         else _putch(SPACE);
  163.  
  164.         if (s = nil) then
  165.           s := PAnsiChar(menu[i]);
  166.  
  167.       end;
  168.       textattr(CYAN<<4 or BLACK);
  169.       _putch(SPACE);
  170.       _putch(ACS_VLINE);
  171.  
  172.     end;
  173.  
  174.     gotoxy(x,y+nitems+1);
  175.     _putch(ACS_LLCORNER);
  176.  
  177.     i := 0;
  178.     while (i < (width+2)) do
  179.     begin
  180.       _putch(ACS_HLINE);
  181.       i := i + 1;
  182.     end;
  183.     _putch(ACS_LRCORNER);
  184.  
  185.    key := _getch;
  186.    case (key) of
  187.       KB_UP: begin if (itemno > 0) then itemno := itemno - 1  else itemno := nitems-1; end;
  188.       KB_DOWN: begin Inc(itemno); itemno := itemno mod nitems; end;
  189.       KB_ESC: begin cursoron(); result := 0; exit; end;
  190.       KB_ENTER: begin cursoron(); result := itemno+1; exit; end;
  191.    end;
  192.  end;
  193. end;
  194.  
  195.  
  196. procedure drawbox(x, y, width, height, color, border: integer);
  197. var
  198.   i, j: integer;
  199. begin
  200.     if (x < 1) then x := 1;
  201.     if (y < 1) then y := 1;
  202.     if (x > 80) then x := 80;
  203.     if (y > 24) then y := 24;
  204.     if (width < 1) then width := 1;
  205.     if (height < 0) then height := 0;
  206.  
  207.     textattr(color);
  208.     gotoxy(x,y);
  209.  
  210.     if (border = 1) then
  211.     begin
  212.       _putch(ACS_ULCORNER);
  213.       i := 0;
  214.       while (i < width+1) do
  215.       begin
  216.            _putch(ACS_HLINE);
  217.            Inc(i);
  218.       end;
  219.       _putch(ACS_URCORNER);
  220.     end
  221.     else
  222.     begin
  223.       _putch(SPACE);
  224.        i := 0;
  225.       while (i < width+1) do
  226.       begin
  227.          _putch(SPACE);
  228.       end;
  229.       _putch(SPACE);
  230.     end;
  231.  
  232.     if (border = 1) then
  233.     begin
  234.       for i := 0 to (height-1) do
  235.       begin
  236.           gotoxy(x,y+i+1);
  237.           _putch(ACS_VLINE);
  238.           _putch(SPACE);
  239.  
  240.           for j := 0 to  (width-1) do
  241.           begin
  242.               _putch(SPACE);
  243.           end;
  244.           _putch(ACS_VLINE);
  245.       end;
  246.     end
  247.     else
  248.     begin
  249.       for i := 0 to (height-1) do
  250.       begin
  251.         gotoxy(x,y+i+1);
  252.         _putch(SPACE);
  253.         _putch(SPACE);
  254.  
  255.         for j := 0 to (width-1) do
  256.         begin
  257.             _putch(SPACE);
  258.         end;
  259.         _putch(SPACE);
  260.       end;
  261.     end;
  262.  
  263.     if (border = 1) then
  264.     begin
  265.       gotoxy(x,y+height+1);
  266.       _putch(ACS_LLCORNER);
  267.       i := 0;
  268.       while (i < (width+1)) do
  269.       begin
  270.          _putch(ACS_HLINE);
  271.          Inc(i);
  272.        end;
  273.       _putch(ACS_LRCORNER);
  274.     end
  275.     else
  276.     begin
  277.       gotoxy(x,y+height+1);
  278.       _putch(SPACE);
  279.       i := 0;
  280.       while (i < (width+1)) do
  281.       begin
  282.            _putch(SPACE);
  283.            Inc(i);
  284.       end;
  285.       _putch(SPACE);
  286.     end;
  287.     textattr(LIGHTGRAY or BLACK <<4);
  288. end;
  289.  
  290.  
  291. procedure drawboxnum(num, x, y, color, border: integer);
  292. var
  293.   i, j, width, height: integer;
  294. begin
  295.     if ((num < 48) or (num > 57)) then exit;
  296.  
  297.     width := 2;
  298.     height := 1;
  299.  
  300.     if (x < 1) then x := 1;
  301.     if (y < 1) then y := 1;
  302.     if (x > 80) then x := 80;
  303.     if (y > 24) then y := 24;
  304.     if (width < 1) then width := 1;
  305.     if (height < 0) then height := 0;
  306.  
  307.     textattr(color);
  308.     gotoxy(x,y);
  309.  
  310.     if (border = 1) then
  311.     begin
  312.       _putch(ACS_ULCORNER);
  313.       i := 0;
  314.       while (i < width+1) do
  315.       begin
  316.            _putch(ACS_HLINE);
  317.            Inc(i);
  318.       end;
  319.       _putch(ACS_URCORNER);
  320.     end
  321.     else
  322.     begin
  323.       _putch(SPACE);
  324.        i := 0;
  325.       while (i < width+1) do
  326.       begin
  327.          _putch(SPACE);
  328.       end;
  329.       _putch(SPACE);
  330.     end;
  331.  
  332.     if (border = 1) then
  333.     begin
  334.       for i := 0 to (height-1) do
  335.       begin
  336.           gotoxy(x,y+i+1);
  337.           _putch(ACS_VLINE);
  338.           _putch(SPACE);
  339.  
  340.           for j := 0 to  (width-1) do
  341.           begin
  342.                if (j = 0) then _putch(num)
  343.               else _putch(SPACE);
  344.           end;
  345.           _putch(ACS_VLINE);
  346.       end;
  347.     end
  348.     else
  349.     begin
  350.       for i := 0 to (height-1) do
  351.       begin
  352.         gotoxy(x,y+i+1);
  353.         _putch(SPACE);
  354.         _putch(SPACE);
  355.  
  356.         for j := 0 to (width-1) do
  357.         begin
  358.              if (j = 0) then _putch(num)
  359.             else _putch(SPACE);
  360.         end;
  361.         _putch(SPACE);
  362.       end;
  363.     end;
  364.  
  365.     if (border = 1) then
  366.     begin
  367.       gotoxy(x,y+height+1);
  368.       _putch(ACS_LLCORNER);
  369.       i := 0;
  370.       while (i < (width+1)) do
  371.       begin
  372.          _putch(ACS_HLINE);
  373.          Inc(i);
  374.        end;
  375.       _putch(ACS_LRCORNER);
  376.     end
  377.     else
  378.     begin
  379.       gotoxy(x,y+height+1);
  380.       _putch(SPACE);
  381.       i := 0;
  382.       while (i < (width+1)) do
  383.       begin
  384.            _putch(SPACE);
  385.            Inc(i);
  386.       end;
  387.       _putch(SPACE);
  388.     end;
  389.     textattr(LIGHTGRAY or BLACK <<4);
  390. end;
  391.  
  392. end.
  393.  
  394.  

i can't post all program because is limited to 20000 car. on the forum.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Pointeur to string on loop equivalent to C
« Reply #12 on: November 25, 2020, 05:53:22 pm »
i can't post all program because is limited to 20000 car. on the forum.

Yes, you can. See Forum: Sharing large pieces of code in the wiki. :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

andromeda

  • New Member
  • *
  • Posts: 12
Re: Pointeur to string on loop equivalent to C
« Reply #13 on: November 25, 2020, 06:05:08 pm »
i have attached zip file from my project. this project use lazserial and synapse for synaser, com port and baud are defined on conio.pas  on procedure initconio/

 

TinyPortal © 2005-2018