Announcement

Collapse
No announcement yet.

Convert c style text

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Jeff Blakeney
    replied
    Tom, as long as you are aware of escaped escape characters, you can get around them. Instead of doing a REPLACE "\\" WITH "\" in sFormat you could do a REPLACE "\\" WITH $NUL IN sFormat before doing all the other escape character replaces and then do a REPLACE $NUL WITH "\" IN sFormat when you are done. In your example of "\\r" the "\\" would get replaced with a null so the string would then be $NUL + "r". After replacing all the other escaped characters the null would be replaced with "\" leaving you with the string "\r".

    To be safer, instead of hard coding a null, you could first do a loop looking for a character or character sequence that doesn't exist in sFormat and using that as nulls might appear in sFormat. Because I found myself writing this sort of loop a number of times I ended up writing a routine called GetUniqueDelimiter that will find a single character that doesn't exist in the string passed in but I never did get around to adding the multiple character sequences. Comes in handy when you load a file and want to change all the end of line characters to a whatever you want. You get a unique delimiter that doesn't exist in the file and replace CRLF, CR and LF with that delimiter and then replace that delimiter with whatever end of line you want and the rest of the data remains intact.

    However, as you said, doing a sequential scan through the string might be better in this case seeing as many of the format codes can be prefixed and suffixed with other characters. Might as well just deal with the escaped characters (starting with \) when you run into them while looking for format codes (starting with %).

    Leave a comment:


  • Michael Mattias
    replied
    > is that the escape character may be escaped

    That's because 'c' compilers do 'escaping' at compile time to allow for the shorthand "\n" or "\t" notation in the programmer's source code.

    The PB compilers don't use shorthand stuff requiring escaping at compile time; eg here "\n" and "\t" would be "$LF" and "$TAB" in the source code.

    (Except maybe for $DQ? Since I'm unsure is one more reason I avoid using inline literals).

    MCM

    Leave a comment:


  • Tom Hanlin
    replied
    One thing to bear in mind, if you're planning to do your own conversions, is that the escape character may be escaped. It's not safe to just use a REPLACE statement, since "'\\r" should mean "\r", where "m\r" turns into "m"+$CR ...in fact, you'll often see escaped escapes in C strings that contain paths.

    You'll get better results doing a sequential scan through the string.

    Leave a comment:


  • Michael Mattias
    replied
    >The data type is specified in the format string

    Ooh, ooh, I did not notice that. That eliminates most of the problems....
    Code:
    UNION pfvar 
       S  AS SINGLE PTR 
       D  AS DOUBLE PTR 
       W  AS WORD PTR 
       sz  AS ASCIIZ PTR 
       bStr AS STRING PTR 
       ....
    END UNION  
    FUNCTION Printf( szformat AS ASCIIZ, v1 AS PFVar, OPT v2 AS PFVar, v3 AS pvVar..
    
    END FUNCTiON
    Now everything is reduced to a simple exercise in string parsing!

    (You might still want to put in a DLL so you can DECLARE it with all the "AS ANY")

    MCM

    Leave a comment:


  • Jeff Blakeney
    replied
    Originally posted by Michael Mattias View Post
    You have three 'real' problems creating your own "printf"

    First, printf accepts a variable number of parameters, and the c compiler sorts that out at compile time. You could come really close by making a function like.....
    Code:
    FUNCTION printf( szFormatString AS ASCIIZ, v1 AS ANY, OPT v2 as AnY, v3 as ANY... v31 AS ANY) AS LONG
    ... where the 32 params total (string + 31 variables) is the limit of the PB compilers.
    Yes, you could limit the number of parameters or you could change it to only two parameters, the format string and either a pointer to the start of a linked list or an array of pointers. Creating the linked list or array before calling a new printf wouldn't be as nice as the C version of printf but it would get around the limited parameters situation.

    But that bring us to problem two... The PB compiler will not create a function with "AS ANY" in the procedure header. You could get around that by putting the function into a DLL with "BYVAL AS DWORD" (an address) params for the optional params, and in the calling program it is now perfectly permissible to DECLARE the function with "AS ANY" parameters.
    If you use a linked list or an array of pointers you will, in effect, be passing a pointer to a DWORD so you don't need to use the ANY keyword.

    But that brings us to problem number three, which is, the PB compiler requires the datatype of the passed parameters to use FORMAT$() or USING$() or any other "formatting function." .. and given only an address, you have no idea what kind of data is at that address, so you might be SOL......
    The data type is specified in the format string. If you use printf("%d = %s", StringAddr, StringAddr) you will get a decimal representation of the StringAddr followed by " = " followed by the string. Also, if you go with the linked list then that could also keep the data type with it and using an array you could make it two dimenional so that you can have both the data type and value but I think using the type implied by the format string would be more straight forward.

    Except... even that you could work around .... by making all your parameter variables type VARIANT and querying the type of data with the VARIANTVT function.
    Variants would work too. The array I suggested about could be an array of variants instead of an array of pointers but I don't think needing to know the variable type is all that important in this particular case because commands like FORMAT$ work with any numeric data type.

    Your "slow" complaint is a red herring. Sheesh, you are writing to STDOUT, so that I-O is probably the limiting factor anyway.
    I did qualify by saying that it would only be a problem if you were doing a lot of printing. I've tested REGEXPR before and for the applications I've tried it, I've always found it faster to write my own code to find the data I want.

    What, you think the guys at PB can't format strings just as fast as the guys from Microsoft who created the 'printf' statement for their c compilers? I sure think they can.
    I never said that PB's string formatting was slow, I said REGEXPR and REGREPL were slow. One of the reasons I love PB so much is the string handling capabilities.

    Have some faith in the Floridians!
    I do. Otherwise, I wouldn't be using their products.

    MCM
    (Or ask for a 'printf' equivalent as a 'New Feature Suggestion' )
    The original poster was looking for this functionality, not me. I never much liked printf as I find it overly complicated. I'd rather just use string concatenation and/or USING$.

    Leave a comment:


  • Michael Mattias
    replied
    You have three 'real' problems creating your own "printf"

    First, printf accepts a variable number of parameters, and the c compiler sorts that out at compile time. You could come really close by making a function like.....
    Code:
    FUNCTION printf( szFormatString AS ASCIIZ, v1 AS ANY, OPT v2 as AnY, v3 as ANY... v31 AS ANY) AS LONG
    ... where the 32 params total (string + 31 variables) is the limit of the PB compilers.

    But that bring us to problem two... The PB compiler will not create a function with "AS ANY" in the procedure header. You could get around that by putting the function into a DLL with "BYVAL AS DWORD" (an address) params for the optional params, and in the calling program it is now perfectly permissible to DECLARE the function with "AS ANY" parameters.

    But that brings us to problem number three, which is, the PB compiler requires the datatype of the passed parameters to use FORMAT$() or USING$() or any other "formatting function." .. and given only an address, you have no idea what kind of data is at that address, so you might be SOL......

    Except... even that you could work around .... by making all your parameter variables type VARIANT and querying the type of data with the VARIANTVT function.

    Your "slow" complaint is a red herring. Sheesh, you are writing to STDOUT, so that I-O is probably the limiting factor anyway.

    What, you think the guys at PB can't format strings just as fast as the guys from Microsoft who created the 'printf' statement for their c compilers? I sure think they can.

    Have some faith in the Floridians!

    MCM
    (Or ask for a 'printf' equivalent as a 'New Feature Suggestion' )

    Leave a comment:


  • Jeff Blakeney
    replied
    Originally posted by Michael Mattias View Post
    REGREPL could be be a really easy way to convert from a "c-style formatting string" to a Pb-Style 'mask' for use with USING$() and a variable list, or to a CHR$() string.
    In my mind, the word "easy" is never associated with REGREPL or REGEXPR. Also, the REGxxxx commands aren't very fast so if you need to do a lot of them your code would slow down a lot.

    Also, like I mentioned in my previous post in this thread, there is also still the problem of being able to specify that a number be displayed in octal, hexadecimal or scientific notation or to restrict the precision of the displayed number and those options don't exist with USING$.

    It would be possible, but again I wouldn't say it is easy, to write your own printf routine that worked just like the C command.

    Leave a comment:


  • Michael Mattias
    replied
    REGREPL could be be a really easy way to convert from a "c-style formatting string" to a Pb-Style 'mask' for use with USING$() and a variable list, or to a CHR$() string.

    Leave a comment:


  • Fred Harris
    replied
    But if you don't need a console window wsprintf gets realy easy like Jose showed. Here is output to a text box where I output an integer (%u)...

    Code:
    #Compile       Exe
    #Include       "Win32api.inc"
    %IDC_BUTTON    =2000
    %IDC_TEXT      =2002
    
    Type WndEventArgs
      wParam As Long
      lParam As Long
      hWnd   As Dword
      hInst  As Dword
    End Type
    
    Declare Function FnPtr(wea As WndEventArgs) As Long
    
    Type MessageHandler
      wMessage As Long
      dwFnPtr As Dword
    End Type
    Global MsgHdlr() As MessageHandler
    
    
    Sub Command1_OnClick(Wea As WndEventArgs)
      Local szOutput As Asciiz*64
      Local iWt As Long
      iWt=210
      wsprintf(szOutput, "My Name Is Fred And I Weigh %u Pounds!", Byval iWt)
      Call SetWindowText(GetDlgItem(Wea.hWnd,%IDC_TEXT),szOutput)
    End Sub
    
    
    Function fnWndProc_OnCreate(wea As WndEventArgs) As Long
      Local pCreateStruct As CREATESTRUCT Ptr
      Local hCtl As Dword
    
      pCreateStruct=wea.lParam
      [email protected]
      hCtl=CreateWindow("button","Do Some wsprintf!",%WS_CHILD Or %WS_VISIBLE,110,15,140,30,wea.hWnd,%IDC_BUTTON,wea.hInst,Byval 0)
      hCtl=CreateWindowEx(%WS_EX_CLIENTEDGE,"Edit","",%WS_CHILD Or %WS_VISIBLE,20,60,320,25,wea.hWnd,%IDC_TEXT,wea.hInst,Byval 0)
    
      fnWndProc_OnCreate=0
    End Function
    
    
    Function fnWndProc_OnCommand(wea As WndEventArgs) As Long
      Select Case As Long Lowrd(wea.wParam)
        Case %IDC_BUTTON
          Call Command1_OnClick(wea)
      End Select
    
      fnWndProc_OnCommand=0
    End Function
    
    
    Function fnWndProc_OnClose(wea As WndEventArgs) As Long
      Call PostQuitMessage(0)
      fnWndProc_OnClose=0
    End Function
    
    
    Function fnWndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
      Local wea As WndEventArgs
      Register iReturn As Long
      Register i As Long
    
      For i=0 To 2
        If wMsg=MsgHdlr(i).wMessage Then
           wea.hWnd=hWnd: wea.wParam=wParam: wea.lParam=lParam
           Call Dword MsgHdlr(i).dwFnPtr Using FnPtr(wea) To iReturn
           fnWndProc=iReturn
           Exit Function
        End If
      Next i
    
      fnWndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
    End Function
    
    
    Sub AttachMessageHandlers()
      ReDim MsgHdlr(2) As MessageHandler   'Associate Windows Message With Message Handlers
      MsgHdlr(0).wMessage=%WM_CREATE   :   MsgHdlr(0).dwFnPtr=CodePtr(fnWndProc_OnCreate)
      MsgHdlr(1).wMessage=%WM_COMMAND  :   MsgHdlr(1).dwFnPtr=CodePtr(fnWndProc_OnCommand)
      MsgHdlr(2).wMessage=%WM_CLOSE    :   MsgHdlr(2).dwFnPtr=CodePtr(fnWndProc_OnClose)
    End Sub
    
    
    Function WinMain(ByVal hIns As Long, ByVal hPrevIns As Long, ByVal lpCmdLn As Asciiz Ptr, ByVal iShowWnd As Long) As Long
      Local szAppName As Asciiz*16
      Local wc As WndClassEx
      Local hWnd As Dword
      Local Msg As tagMsg
    
      Call AttachMessageHandlers()                       : szAppName="wsprintf"
      wc.lpszClassName=VarPtr(szAppName)                 : wc.lpfnWndProc=CodePtr(fnWndProc)
      wc.cbSize=SizeOf(wc)                               : wc.style=%CS_HREDRAW Or %CS_VREDRAW
      wc.cbClsExtra=0                                    : wc.cbWndExtra=0
      wc.hInstance=hIns                                  : wc.hIcon=LoadIcon(%NULL, ByVal %IDI_APPLICATION)
      wc.hCursor=LoadCursor(%NULL, ByVal %IDC_ARROW)     : wc.hbrBackground=%COLOR_BTNFACE+1
      wc.lpszMenuName=%NULL
      Call RegisterClassEx(wc)
      hWnd=CreateWindowEx(0,szAppName,"wsprintf",%WS_OVERLAPPEDWINDOW Xor %WS_MAXIMIZEBOX,400,300,375,150,0,0,hIns,ByVal 0)
      Call ShowWindow(hWnd,iShowWnd)
      While GetMessage(Msg,%NULL,0,0)
        TranslateMessage Msg
        DispatchMessage Msg
      Wend
    
      Function=msg.wParam
    End Function

    Leave a comment:


  • Fred Harris
    replied
    wsprintf

    ...and I got this to work with wsprintf which is as mentioned in Win32Api.inc...

    Code:
    'Program demonstrates how to restore standard output handle in C Runtime Library
    'which is zeroed out by initialization of GUI process.
    #Compile Exe
    #Include "Win32api.inc"           'Translation of Windows.h for PowerBASIC
    %IDC_BUTTON1 = 1250               'ctrl id of button
    %O_TEXT      = &H4000             'from Fcntl.h
    
    Type FILE      'From stdio.h      'When a GUI application is started the three standard OS handles
      pChar        As Asciiz Ptr      'STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all
      cnt          As Long            'zeroed out by the console initialization routines.  These three
      pBase        As Asciiz Ptr      'handles are replaced by valid values when a GUI application calls
      flag         As Long            'AllocConsole(). Therefore, once this is done, calling GetStdHandle()
      fil          As Long            'will always return valid handle values. The problem is that the
      charbuf      As Long            'CRT has already completed initialization before an application gets
      bufsize      As Long            'a chance to call AllocConsole(); the three low I/O handles 0, 1,
      TmpFileName  As Asciiz Ptr      'and 2 have already been set up to use the original zeroed out OS
    End Type                          'handles, so all CRT I/O is sent to invalid OS handles and CRT output
                                      'does not appear in the console.
    
    Declare Function GetConsoleWindow Lib "Kernel32.dll" Alias "GetConsoleWindow" () As Dword
    
    
    Declare Function printf CDecl Lib "msvcrt.dll" Alias "printf" _   'printf from stdio.h
    ( _
      szFmtStr As Asciiz _
      [, _
         lpVar1 As Any, _
         lpVar2 As Any, _
         lpVar3 As Any, _
         lpVar4 As Any _
      ] _
    ) As Long
    
    
    Declare Function Open_OSFileHandle CDecl Lib "msvcrt.dll" Alias "_open_osfhandle" _  'from IO.h
    ( _
      Byval hHandle As Long, _
      Byval iType   As Long _
    ) As Long
    
    
    Declare Function FDOpen CDecl Lib "msvcrt.dll" Alias "_fdopen" _   'from stdio.h
    ( _
      Byval hHandle As Long, _
      ByRef pszStr As Asciiz _
    ) As Dword
    
    
    Function WndProc(Byval hWnd As Long,Byval wMsg As Long,Byval wParam As Long,Byval lParam As Long) As Long
      Select Case wMsg
        Case %WM_CREATE
          Local hButton As Dword
          Local hIns As Dword
          hIns=GetModuleHandle(Byval 0)
          hButton=CreateWindow("button","Show Console!",%WS_CHILD Or %WS_VISIBLE,110,65,200,25,hWnd,%IDC_BUTTON1,hIns,Byval 0)
          WndProc=0
          Exit Function
        Case %WM_COMMAND
          If Lowrd(wParam)=%IDC_BUTTON1 And HiWrd(wParam)=%BN_CLICKED Then
             Local hStdOutput As Dword              'Standart Output Handle
             Local hf,ptrFile As FILE Ptr           'FILE *
             Local hDll,hCrt,dwWeight As Dword
             Local hSysMenu As Dword
             Register i As Long
             hDll=LoadLibrary("msvcrt.dll")         'Load/Increment Reference Count on msvcrt.dll
             If hDll Then                           'Get base address of exported symbol _iob from msvcrt.dll.  _iob is an
                ptrFile=GetProcAddress(hDll,"_iob") 'array of FILE structs that holds the stdin, stdout, and stderr handles.
                Call AllocConsole()                 'These handels are zeroed out at initialization of a GUI process, and
                hSysMenu=GetSystemMenu(GetConsoleWindow(),Byval 0)   'must be reset with valid operating system handles if
                Call DeleteMenu(hSysMenu,6,%MF_BYPOSITION)           'console output is desired in a GUI process.  With a
                hCrt=Open_OSFileHandle(GetStdHandle(%STD_OUTPUT_HANDLE),%O_TEXT)  'valid handel to stdout returned in hf, it
                hf=FDOpen(hCrt,"w")                 'is restored back in position 1 of the i/o buffer FILE array with
                @ptrFile[1][email protected]                     '@[email protected] printf output using CRT in PowerBASIC!
                dwWeight=210
                Local szOutput As Asciiz*64
                For i=1 To 200     
                  'printf("%d" + Chr$(9) + "My Name Is Fred And I Weigh %u Pounds!" + $Cr + $Lf, Byval i, Byval dwWeight)
                  wsprintf(szOutput, "%d" + Chr$(9) + "My Name Is Fred And I Weigh %u Pounds!" + $Cr + $Lf, Byval i, Byval dwWeight)
                  printf("%s", szOutput)
                Next i
                Call FreeLibrary(hDll)              'Free/decrement reference count on msvcrt.dll
             End If
          End If
          WndProc=0
          Exit Function
        Case %WM_DESTROY
          Call PostQuitMessage(0)
          WndProc=0
          Exit Function
      End Select
    
      WndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
    End Function
    
    Function WinMain(Byval hIns As Long, Byval hPrev As Long, Byval lpCL As Asciiz Ptr, Byval iShow As Long) As Long
      Local szBuffer As Asciiz * 64
      Local wc As WNDCLASSEX
      Local Msg As tagMsg
      Local hWnd As Dword
    
      szBuffer="Console_Output"                           : wc.lpszClAssName=Varptr(szBuffer)
      wc.lpfnWndProc=Codeptr(WndProc)                     : wc.cbSize=Sizeof(wc)
      wc.style=%CS_HREDRAW Or %CS_VREDRAW                 : wc.hInstance=hIns
      wc.cbClsExtra=0                                     : wc.cbWndExtra=0
      wc.hIcon=LoadIcon(%NULL, Byval %IDI_APPLICATION)    : wc.hCursor=LoadCursor(%NULL, Byval %IDC_ARROW)
      wc.hbrBackground=%COLOR_BTNFACE+1                   : wc.lpszMenuName=%NULL
      Call RegisterClAssEx(wc)
      szBuffer="GUI Console Output With C Runtime Library From PowerBASIC!"
      hWnd=CreateWindow("Console_Output",szBuffer,%WS_OVERLAPPEDWINDOW,500,550,440,200,0,0,hIns,Byval 0)
      Call ShowWindow(hWnd,iShow)
      Call UpdateWindow(hWnd)
      While GetMessage(Msg,%NULL,0,0)
        TranslateMessage Msg
        DispatchMessage Msg
      Wend
    
      Function=msg.wParam
    End Function

    Leave a comment:


  • Fred Harris
    replied
    I know I tried that old PB Version 8 printf example of mine sometime after PB 9 came out and found out it wouldn't compile because of this...

    Code:
    Declare Function printf CDecl Lib "msvcrt.dll" Alias "printf" _   'printf from stdio.h
    ( _
      szFmtStr As Asciiz _
      [, _
         Byval lpVar1 As Any, _
         Byval lpVar2 As Any, _
         Byval lpVar3 As Any, _
         Byval lpVar4 As Any _
      ] _
    ) As Long
    Byval ... As Any wasn't allowed anymore. But Jose's idea works with it if you change it to Byref and specify a Byval over ride in the printf call. This works in PB 9...

    Code:
    'Program demonstrates how to restore standard output handle in C Runtime Library
    'which is zeroed out by initialization of GUI process.
    #Compile Exe
    #Include "Win32api.inc"           'Translation of Windows.h for PowerBASIC
    %IDC_BUTTON1 = 1250               'ctrl id of button
    %O_TEXT      = &H4000             'from Fcntl.h
    
    Type FILE      'From stdio.h      'When a GUI application is started the three standard OS handles
      pChar        As Asciiz Ptr      'STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all
      cnt          As Long            'zeroed out by the console initialization routines.  These three
      pBase        As Asciiz Ptr      'handles are replaced by valid values when a GUI application calls
      flag         As Long            'AllocConsole(). Therefore, once this is done, calling GetStdHandle()
      fil          As Long            'will always return valid handle values. The problem is that the
      charbuf      As Long            'CRT has already completed initialization before an application gets
      bufsize      As Long            'a chance to call AllocConsole(); the three low I/O handles 0, 1,
      TmpFileName  As Asciiz Ptr      'and 2 have already been set up to use the original zeroed out OS
    End Type                          'handles, so all CRT I/O is sent to invalid OS handles and CRT output
                                      'does not appear in the console.
    
    Declare Function GetConsoleWindow Lib "Kernel32.dll" Alias "GetConsoleWindow" () As Dword
    
    
    Declare Function printf CDecl Lib "msvcrt.dll" Alias "printf" _   'printf from stdio.h
    ( _
      szFmtStr As Asciiz _
      [, _
         lpVar1 As Any, _
         lpVar2 As Any, _
         lpVar3 As Any, _
         lpVar4 As Any _
      ] _
    ) As Long
    
    
    Declare Function Open_OSFileHandle CDecl Lib "msvcrt.dll" Alias "_open_osfhandle" _  'from IO.h
    ( _
      Byval hHandle As Long, _
      Byval iType   As Long _
    ) As Long
    
    
    Declare Function FDOpen CDecl Lib "msvcrt.dll" Alias "_fdopen" _   'from stdio.h
    ( _
      Byval hHandle As Long, _
      ByRef pszStr As Asciiz _
    ) As Dword
    
    
    Function WndProc(Byval hWnd As Long,Byval wMsg As Long,Byval wParam As Long,Byval lParam As Long) As Long
      Select Case wMsg
        Case %WM_CREATE
          Local hButton As Dword
          Local hIns As Dword
          hIns=GetModuleHandle(Byval 0)
          hButton=CreateWindow("button","Show Console!",%WS_CHILD Or %WS_VISIBLE,110,65,200,25,hWnd,%IDC_BUTTON1,hIns,Byval 0)
          WndProc=0
          Exit Function
        Case %WM_COMMAND
          If Lowrd(wParam)=%IDC_BUTTON1 And HiWrd(wParam)=%BN_CLICKED Then
             Local hStdOutput As Dword              'Standart Output Handle
             Local hf,ptrFile As FILE Ptr           'FILE *
             Local hDll,hCrt,dwWeight As Dword
             Local hSysMenu As Dword
             Register i As Long
             hDll=LoadLibrary("msvcrt.dll")         'Load/Increment Reference Count on msvcrt.dll
             If hDll Then                           'Get base address of exported symbol _iob from msvcrt.dll.  _iob is an
                ptrFile=GetProcAddress(hDll,"_iob") 'array of FILE structs that holds the stdin, stdout, and stderr handles.
                Call AllocConsole()                 'These handels are zeroed out at initialization of a GUI process, and
                hSysMenu=GetSystemMenu(GetConsoleWindow(),Byval 0)   'must be reset with valid operating system handles if
                Call DeleteMenu(hSysMenu,6,%MF_BYPOSITION)           'console output is desired in a GUI process.  With a
                hCrt=Open_OSFileHandle(GetStdHandle(%STD_OUTPUT_HANDLE),%O_TEXT)  'valid handel to stdout returned in hf, it
                hf=FDOpen(hCrt,"w")                 'is restored back in position 1 of the i/o buffer FILE array with
                @ptrFile[1][email protected]                     '@[email protected] printf output using CRT in PowerBASIC!
                dwWeight=210
                Local szBuffer As Asciiz*32
                szBuffer="My Name Is Fred."
                For i=1 To 200                     '
                  printf("%d" + Chr$(9) + "My Name Is Fred And I Weigh %u Pounds!" + $Cr + $Lf, Byval i, Byval dwWeight)
                Next i
                Call FreeLibrary(hDll)              'Free/decrement reference count on msvcrt.dll
             End If
          End If
          WndProc=0
          Exit Function
        Case %WM_DESTROY
          Call PostQuitMessage(0)
          WndProc=0
          Exit Function
      End Select
    
      WndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
    End Function
    
    Function WinMain(Byval hIns As Long, Byval hPrev As Long, Byval lpCL As Asciiz Ptr, Byval iShow As Long) As Long
      Local szBuffer As Asciiz * 64
      Local wc As WNDCLASSEX
      Local Msg As tagMsg
      Local hWnd As Dword
    
      szBuffer="Console_Output"                           : wc.lpszClAssName=Varptr(szBuffer)
      wc.lpfnWndProc=Codeptr(WndProc)                     : wc.cbSize=Sizeof(wc)
      wc.style=%CS_HREDRAW Or %CS_VREDRAW                 : wc.hInstance=hIns
      wc.cbClsExtra=0                                     : wc.cbWndExtra=0
      wc.hIcon=LoadIcon(%NULL, Byval %IDI_APPLICATION)    : wc.hCursor=LoadCursor(%NULL, Byval %IDC_ARROW)
      wc.hbrBackground=%COLOR_BTNFACE+1                   : wc.lpszMenuName=%NULL
      Call RegisterClAssEx(wc)
      szBuffer="GUI Console Output With C Runtime Library From PowerBASIC!"
      hWnd=CreateWindow("Console_Output",szBuffer,%WS_OVERLAPPEDWINDOW,500,550,440,200,0,0,hIns,Byval 0)
      Call ShowWindow(hWnd,iShow)
      Call UpdateWindow(hWnd)
      While GetMessage(Msg,%NULL,0,0)
        TranslateMessage Msg
        DispatchMessage Msg
      Wend
    
      Function=msg.wParam
    End Function
    Not sure if that's what you are getting at. But that printfs text & numbers, i.e., %d, etc.
    Last edited by Fred Harris; 12 Nov 2009, 01:05 PM. Reason: fix typo

    Leave a comment:


  • Edwin Knoppert
    replied
    I have tried the little example from above but that didn't convert the text.
    Frankly, i don't think any conversion is possible, i think the c-compilers do that for us.

    I haven't tried wvsprintf yet since it isn't declared but now i doubt if it will help anyway.

    Unless you fokes know otherwise?

    Leave a comment:


  • Jeff Blakeney
    replied
    There are a lot of things that need to be dealt with when translating a printf to PowerBASIC. PB's USING$ is similar but uses totally different formatting characters. The slash escaped sequences of a printf format string are the easy part as all but the octal number to represent an ASCII character can simply be replaced with the REPLACE command (ie. REPLACE "\r" WITH CHR$(13) IN sFormat). Things get tough when dealing with the % escaped characters because there are multiple number formats including scientific notation, hexadecimal and octal that don't have corresponding codes in PB's USING$. Combine that with the fact that many of these % sequences can start with #-+`' or 0 to change the meaning, can have a field width specified and/or can have a precision specified before you get to that format character it can get pretty crazy.

    Probably the easiest solution would be to create a DLL with C that just puts a wrapper around a printf call and declare that in your PB program and use it. You would have a limited number of parameters but if you really want them to have the ability to use the printf format then that is probably the way to go.

    Leave a comment:


  • Michael Mattias
    replied
    > CHR$("hello", $CRLF, "world", $CRLF, "converted", $TAB, $DQ, text, $DQ)

    I keep forgetting this is not my father's CHR$().

    I do OK picking up the "NEW!" functions, it's using the "IMPROVED!" functions which eludes me.

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by José Roca View Post
    wsprintf does formatting
    So it does. My brain is even worse after midnight!

    Here is the MSDN link:

    Leave a comment:


  • Tom Hanlin
    replied
    It's C that does that peculiar character translation. If you want to map that to PowerBASIC, the syntax will be a little different-- or you could create a translation function.

    "hello\r\nworld\r\nconverted\t\x22text\x22"

    Let's see, the \r is a Return, or $CR. x22 is &H22, or $DQ. Oh, the \t is a tab, $TAB. \n would be Newline, or $LF.

    CHR$("hello", $CRLF, "world", $CRLF, "converted", $TAB, $DQ, text, $DQ)

    ...if I haven't missed anything. The backslash is an escape character in C strings. The argument here is either a letter representing a well-known control code, or a numeric value specifying an ASCII code, where "x" means it's in hex form.

    I seem to recall that the escape code works for everything-- so, "\"foo" is actually another way to say CHR$($DQ, "foo") fer example.
    Last edited by Tom Hanlin; 11 Nov 2009, 10:54 PM.

    Leave a comment:


  • José Roca
    replied
    wsprintf does formatting, but you have to use he correct type characters, e.g.

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "win32api.inc"
    
    FUNCTION PBMAIN () AS LONG
    
       LOCAL szBuffer AS ASCIIZ * 14
       wsprintf szBuffer, "  %02X %02X %02X  ", BYVAL 120, BYVAL 25, BYVAL 33
       ? szBuffer
    
    END FUNCTION
    wvsprintf is the same that wsprintf, but accepting a variable argument list instead of optional parameters. As far as I know, it won't work with PB.

    Leave a comment:


  • Chris Holbrook
    replied
    FWIW wsprintf is declared in win32api.inc...

    MSDN describes wsprintf as
    Code:
    int wsprintf(      
        LPTSTR lpOut,
        LPCTSTR lpFmt,
         ...
    );
    win32api.inc has

    Code:
    #IF %DEF(%NOBYVALPTR)
        DECLARE FUNCTION wsprintf CDECL LIB "USER32.DLL" ALIAS "wsprintfA" (lpOutput AS ASCIIZ, lpFormat AS ASCIIZ, x AS ANY[, x1 AS ANY, x2 AS ANY, x3 AS ANY, x4 AS ANY, x5 AS ANY, x6 AS ANY, x7 AS ANY, x8 AS ANY, x9 AS ANY, _
            x10 AS ANY, x11 AS ANY, x12 AS ANY]) AS LONG
    #ELSE
        DECLARE FUNCTION wsprintf CDECL LIB "USER32.DLL" ALIAS "wsprintfA" (lpOutput AS ASCIIZ, lpFormat AS ASCIIZ, x AS ANY, OPTIONAL x1 AS ANY, OPTIONAL x2 AS ANY, OPTIONAL x3 AS ANY, OPTIONAL x4 AS ANY, OPTIONAL x5 AS ANY, _
            OPTIONAL x6 AS ANY, OPTIONAL x7 AS ANY, OPTIONAL x8 AS ANY, OPTIONAL x9 AS ANY, OPTIONAL x10 AS ANY, OPTIONAL x11 AS ANY, OPTIONAL x12 AS ANY) AS LONG
    #ENDIF
    ...so it insists on three arguments.

    And still does not translate the embedded escaped characters.

    Code:
    #compile exe
    #dim all
    #include "win32api.inc"
    
    function pbmain () as long
        local l as long
        local s as string
        
        s = space$(100)
        wsprintf( byval strptr(s), "hello\r\nworld\r\nconverted\t\x22text\x22", l)
        ? s
        waitkey$
    
    end function
    Aha! wvsprintf does formatting, but is not in win32api.inc.
    Last edited by Chris Holbrook; 11 Nov 2009, 06:13 PM.

    Leave a comment:


  • Edwin Knoppert
    replied
    I would like to provide my users an example how to use C syntax in their BASIC code.
    This means they will type it as they would in c and thus i am not looking for the workarounds here.

    Thanks Jose, i'll check it out!

    Leave a comment:


  • Michael Mattias
    replied
    printf===> STDOUT USING$ (mask, variable [,variable..])

    "hello\r\nworld\r\nconverted\t\x22text\x22"

    The escaped characters ( \anything) may be handled by the c compiler , not the function; this would explain your output.

    You might try
    Code:
    STDOUT   USING$ ("Hello & World & converted &&text&", $CR, $CRLF, $TAB, CHR$(&h22), CHR$(&h22))
    MCM

    Leave a comment:

Working...
X