Hello,
sorry for my english, i'm italian...
I use this command to read input from the user:
Stringa: string;
mov(stdin.a_gets(), Stringa);
This example work well if the user write some text on the console.
But if i want to read some input from another program i lost the last character, for example if another program redirect the input to console and write "xboard", i read in the Stringa variable "xboar".
In Visual Basic net for example i simply can write console.writeline(Stringa) to receive the word "xboard".
Anyone can help me? :bg
Thank's...
Quote from: Andrea Lanza on May 10, 2006, 09:30:24 AM
Hello,
sorry for my english, i'm italian...
I use this command to read input from the user:
Stringa: string;
mov(stdin.a_gets(), Stringa);
This example work well if the user write some text on the console.
But if i want to read some input from another program i lost the last character, for example if another program redirect the input to console and write "xboard", i read in the Stringa variable "xboar".
In Visual Basic net for example i simply can write console.writeline(Stringa) to receive the word "xboard".
Anyone can help me? :bg
Thank's...
I have added this to my list of bugs to check out for the v1.82 release. It may be a few days before I get a chance to look at this as I'm in the middle of a major overhaul of HLA right now (including a lot of testing because the changes are so massive). But I *am* looking into this.
Cheers,
Randy Hyde
Thank's Randall :8)
Hi,
If I wrote this piece of code my HLA program correctly receive the input from another win32 program:
elsewhere i wrote...
w.GetStdHandle(-10);
mov(eax, CanaleIngresso);
w.GetStdHandle(-11);
mov(eax, CanaleUscita);
and this routine correctly catch the string "quit" or everything else...
procedure VerificaComandi;
static(4)
lBytesRead: dword;
buffer : byte[1024];
strings: string[16];
begin VerificaComandi;
w.RtlZeroMemory(&buffer,1024);
w.ReadFile(CanaleIngresso,&buffer,1023,&lBytesRead,NULL);
if (lBytesRead > 0) then
str.tokenize2( &buffer, strings, {' ', #10 });
mov( 0, ebx );
while( ebx < eax ) do
str.ieq(strings[ebx*4],"quit");
if (al) then
call UscitaProgramma;
//w.MessageBox(0,strings[ebx*4],"Matilde", w.MB_OK | w.MB_ICONERROR);
endif;
strfree( strings[ebx*4] );
inc( ebx );
endwhile;
endif;
end VerificaComandi;
But... is there a more simple way to do this?
In C++ I wrote:
char S[256];
gets_s(S, 255);
if (!strcmp(S, "xboard"))
{
i do some work;
}
and this work fine.
I have some problem with a_gets() and gets(S).
many thank's
Andrea Lanza
If you want to use the standard library (high level), try one of these
// for single words
forever
stdout.put ("enter command: ");
mov (stdin.a_gets(), s);
breakif (str.ieq (s, "quit"));
str.free (s);
endfor;
str.free (s);
// quit can be anywhere in string
forever
stdout.put ("enter command string: ");
mov (stdin.a_gets(), s);
breakif (str.iindex (s, "quit")<> -1);
str.free (s);
endfor;
str.free (s);
Thank's but this way don't work.
I must receive command from an external win32 program and this solution works for user input.
I think that the external win32 program send string in another format. Maybe c/c++ strings? Null terminated?
I don't know why i receive the string without the last character for example, the string send is "quit" and with a_gets() i receive "qui".
The piece of code that i previous wrote work, but i looking for a simple way to do this.
Any suggestion?
Thank's
Andrea
Well, I don't really have a much better solution... if a_gets() doesn't work, there is probably something wrong with the routine which should be reported to Randall Hyde. I'll also take a look at it when I get the time.
In the meantime, there is a flaw in your program that will inevitably cause it to work incorrectly, also a couple of suggestions.
procedure VerificaComandi;
static(4)
lBytesRead: dword;
buffer : byte[1024];
strings: string[16];
begin VerificaComandi;
w.RtlZeroMemory(&buffer,1024);
w.ReadFile(CanaleIngresso,&buffer,1023,&lBytesRead,NULL);
if (lBytesRead > 0) then
RtlZeroMemory is not needed above as ReadFile will copy a zerro-terminated string to the buffer.
Also, readfile returns >0 in eax if it was successful, so you could just write:
if (eax) then ...
Quote
str.tokenize2( &buffer, strings, {' ', #10 });
mov( 0, ebx );
while( ebx < eax ) do
str.ieq(strings[ebx*4],"quit");
if (al) then
call UscitaProgramma;
//w.MessageBox(0,strings[ebx*4],"Matilde", w.MB_OK | w.MB_ICONERROR);
endif;
strfree( strings[ebx*4] );
inc( ebx );
endwhile;
endif;
end VerificaComandi;
Okay, the bug in this is in the while loop.
You use:
while (ebx < eax) do...
but then, str.eq changes eax into either 0 or 1, which will will mean that your while loop ends after the 1st iteration and the rest of the tokenized strings don't get freed.
fixed while loop:
while( ebx < eax ) do
push (eax); // preserve eax
str.ieq(strings[ebx*4],"quit");
if (al) then
call UscitaProgramma;
//w.MessageBox(0,strings[ebx*4],"Matilde", w.MB_OK | w.MB_ICONERROR);
endif;
strfree( strings[ebx*4] );
inc( ebx );
pop (eax); // restore eax
endwhile;
Another potential problem: str.tokenize2 expects HLA strings, so it *may* (not certain) malfunction sometime.
Instead of tokenize, you could use str.a_cpyz and str.index combination.
procedure VerificaComandi;
static(4)
lBytesRead: dword;
buffer : byte[1024];
begin VerificaComandi;
w.ReadFile(CanaleIngresso,&buffer,1023,&lBytesRead,NULL);
if (eax) then
str.a_cpyz (&buffer);
mov (eax, ebx); // save string here temporarily
if ( str.index ( ebx, "quit") <> -1 ) then
call UscitaProgramma;
endif;
str.free (ebx);
endif;
end VerificaComandi;
Not much better, but a little smaller, and also has a limitation. If the string contains "quitit", UscitaProgramma will still be called.
:U Thank you very much for your suggestion.
Now the code is more readable and i will use it for my program.
Andrea Lanza