Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Escaping of quotes in parameters?

15 views
Skip to first unread message

Tim

unread,
Mar 27, 2007, 6:45:23 PM3/27/07
to
Hi,

I have a problem with quotes in parameters. I use
ShowMessage(ParamStr(1)); to display the first parameter. But I don't
know how to form the parameter, so that it displays 1"2.
I've already tried these three methods - but none of them outputs
exactly what I want. Do I have to make modifications in the
GetParamStr() function? Or which other alternatives are available
(replacing,...)?

application.exe "1""2" //outputs 12
application.exe "1"2" //outputs 12
application.exe "1\"2" //outputs 1\2

Thanks in advance for your help!

Best regards,
Tim

Remy Lebeau (TeamB)

unread,
Mar 27, 2007, 10:31:40 PM3/27/07
to

"Tim" <downlo...@gmx.net> wrote in message
news:46099ec4$1...@newsgroups.borland.com...

> I have a problem with quotes in parameters.

ParamStr() can't handle quotations in parameters like you are trying
to use. You will have to call GetCommandLine() and then manually
parse the parameters.

> I don't know how to form the parameter, so that it displays 1"2.

You can't if you use ParamStr().

> application.exe "1""2" //outputs 12
> application.exe "1"2" //outputs 12
> application.exe "1\"2" //outputs 1\2

ParamStr() strips out quotations from a parameter.

ParamStr() (and indirectly, ParamCount()) needs to be seriously
rewritten by Borland/CodeGear, in my opinion. It is horribly
inaccurate. It doesn't even follow the same parsing rules that
Microsoft uses at the command prompt. See QC #3946, #27451, and
#43340 for more details.


Gambit


Rob Kennedy

unread,
Mar 27, 2007, 10:46:34 PM3/27/07
to
Remy Lebeau (TeamB) wrote:
> "Tim" <downlo...@gmx.net> wrote in message
> news:46099ec4$1...@newsgroups.borland.com...
>> I have a problem with quotes in parameters.
>
> ParamStr() can't handle quotations in parameters like you are trying
> to use. You will have to call GetCommandLine() and then manually
> parse the parameters.

For easy parsing, I like to call CommandLineToArgvW. Use GetCommandLineW
to get the original Unicode command line from the OS.

--
Rob

Remy Lebeau (TeamB)

unread,
Mar 28, 2007, 1:29:57 AM3/28/07
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:4609c5de$1...@newsgroups.borland.com...

> ParamStr() can't handle quotations in parameters like you are
> trying to use. You will have to call GetCommandLine()
> and then manually parse the parameters.

Here is some code I just write to do that, based on parsing rules that
are documented at MSDN:

function GetNextParam(var CmdLine: PChar; Buffer: PChar; Len:
PInteger): Boolean;
var
InQuotedStr, IsOdd: Boolean;
NumSlashes, NewLen, I: Integer;
begin
Result := False;
if Len <> nil then Len^ := 0;
if CmdLine = nil then Exit;
while (CmdLine^ <= ' ') and (CmdLine^ <> #0) do
CmdLine := CharNext(CmdLine);
if CmdLine^ = #0 then Exit;
InQuotedStr := False;
NewLen := 0;
repeat
if CmdLine^ = '\' then
begin
NumSlashes := 0;
repeat
Inc(NumSlashes);
CmdLine := CharNext(CmdLine);
until CmdLine^ <> '\';
if CmdLine^ = '"' then
begin
IsOdd := (NumSlashes mod 2) <> 0;
NumSlashes := NumSlashes div 2;
Inc(NewLen, NumSlashes);
if IsOdd then Inc(NewLen);
if Buffer <> nil then
begin
for I := 0 to NumSlashes-1 do
begin
Buffer^ := '\';
Inc(Buffer);
end;
if IsOdd then
begin
Buffer^ := '"';
Inc(Buffer);
end;
end;
if IsOdd then CmdLine := CharNext(CmdLine);
end else
begin
Inc(NewLen, NumSlashes);
if Buffer <> nil then
begin
for I := 0 to NumSlashes-1 do
begin
Buffer^ := '\';
Inc(Buffer);
end;
end;
end;
Continue;
end;
if CmdLine^ <> '"' then
begin
if (CmdLine^ <= ' ') and (not InQuotedStr) then Break;
Inc(NewLen);
if Buffer <> nil then
begin
Buffer^ := CmdLine^;
Inc(Buffer);
end;
end else
InQuotedStr := not InQuotedStr;
CmdLine := CharNext(CmdLine);
until CmdLine^ = #0;
if Len <> nil then Len^ := NewLen;
Result := True;
end;

function GetParamStr(Index: Integer): String;
var
Buffer: array[0..MAX_PATH] of Char;
CmdLine, P: PChar;
Len: Integer;
begin
Result := '';
if Index <= 0 then
begin
Len := GetModuleFileName(0, Buffer, MAX_PATH+1);
SetString(Result, Buffer, Len);
end else
begin
CmdLine := GetCommandLine;
GetNextParam(CmdLine, nil, nil);
repeat
Dec(Index);
if Index = 0 then Break;
if not GetNextParam(CmdLine, nil, nil) then Exit;
until False;
P := CmdLine;
if GetNextParam(P, nil, @Len) then
begin
SetLength(Result, Len);
GetNextParam(CmdLine, PChar(Result), nil);
end;
end;
end;

function GetParamCount: Integer;
var
CmdLine: PChar;
begin
Result := 0;
CmdLine := GetCommandLine;
GetNextParam(CmdLine, nil, nil);
while GetNextParam(CmdLine, nil, nil) do Inc(Result);
end;


Gambit


Tim

unread,
Mar 28, 2007, 11:32:57 AM3/28/07
to
> ParamStr() (and indirectly, ParamCount()) needs to be seriously
> rewritten by Borland/CodeGear, in my opinion. It is horribly
> inaccurate. It doesn't even follow the same parsing rules that
> Microsoft uses at the command prompt. See QC #3946, #27451, and
> #43340 for more details.
OK. Thanks for reporting it.

These functions work perfectly.

Thank you very much for all your help!

Best regards,
Tim

0 new messages