1. getc/ReadFile after gets problem
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Dec 07, 2006
- 633 views
I think there is some wierd buffer-effect going on inside gets/getc. After gets(0), getc(0) will wait for new input, whereas a call to the windows API function, c_func(xReadFile,{stdin,chr,1,count,0}) yields both the \r and \n, that I thought would have been "eaten" by gets(0)?? Here is some code that behaves strangely, any clues?:
include dll.e include machine.e atom xKernel32,xGetStdHandle,xReadFile integer cinit cinit=0 constant C_PTR = C_POINTER constant STD_INPUT_HANDLE = -10 -- #FFFFFFF6 atom stdin, character, bytes_count procedure Cinit() xKernel32 = open_dll("kernel32.dll") if xKernel32 = 0 then ?9/0 end if xGetStdHandle = define_c_func(xKernel32,"GetStdHandle", {C_LONG}, -- DWORD nStdHandle // input, output, or error device C_PTR) -- HANDLE xReadFile = define_c_func(xKernel32,"ReadFile", {C_PTR, -- HANDLE hFile, // handle of file to read C_PTR, -- LPVOID lpBuffer, // address of buffer that receives data C_LONG, -- DWORD nNumberOfBytesToRead, // number of bytes to read C_PTR, -- LPDWORD lpNumberOfBytesRead, // address of number of bytes read C_PTR}, -- LPOVERLAPPED lpOverlapped // address of structure for data C_INT) -- BOOL stdin = c_func(xGetStdHandle,{STD_INPUT_HANDLE}) character = allocate(1) bytes_count = allocate(4) cinit=1 end procedure function mygetc0() integer ch if not cinit then Cinit() end if while 1 do if not c_func(xReadFile,{stdin,character,1,bytes_count,0}) then return -1 end if ch = peek(character) if ch!='\r' then exit end if end while return ch end function ?gets(0) --?getc(0) -- <<<--- swap me ?mygetc0() -- <<<--- with me ?1.234 abort(0)
With getc(0), type in "ABC\n", it outputs {65,66,67,10} and waits for input. With mygetc(0), it outputs the 10 twice, but you only need to key it once! Does anyone (with some knowledge, perhaps, of C|be_runtime.c) have any Ideas? There is something Somewhere in there it (I think) shoves a read character back into the input stream, but I can't follow C code with all those #ifdefs... Regards, Pete
2. Re: getc/ReadFile after gets problem
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Dec 07, 2006
- 643 views
Pete Lomax wrote: > > I think there is some wierd buffer-effect going on inside gets/getc. > After gets(0), getc(0) will wait for new input, whereas a call to the > windows API function, c_func(xReadFile,{stdin,chr,1,count,0}) yields > both the \r and \n, that I thought would have been "eaten" by gets(0)?? > > Here is some code that behaves strangely, any clues?: <snip> > > With getc(0), type in "ABC\n", it outputs {65,66,67,10} and waits for input. > With mygetc(0), it outputs the 10 twice, but you only need to key it once! > > Does anyone (with some knowledge, perhaps, of C|be_runtime.c) have any Ideas? > There is something > Somewhere in there it (I think) shoves a read character back into the input > > stream, but I can't follow C code with all those #ifdefs... > I think the problem is in be_runtime.c/key_gets(). if (c == '\r' || c == '\n' #ifdef EWINDOWS || c == 284 #endif ) break; else if (c == BS || c == LEFT_ARROW #ifdef ELINUX //FOR NOW - must decide what to do about different key codes || c == 263 #endif ) { if (column > init_column) { column = column - 1; SetPosition(line, column); screen_output(NULL, " "); SetPosition(line, column); input_string[column - init_column] = '\0'; } } You'll notice that eu will delete the character if you use the left arrow, where as windows will just move the cursor. The solution is probably to output the newline, and to get rid of the screen_output(NULL, " ") in the left arrow case. Matt
3. Re: getc/ReadFile after gets problem
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Dec 08, 2006
- 632 views
Matt Lewis wrote: > > I think the problem is in be_runtime.c/key_gets(). Hmmm, the more I stare at wingetch() etc the more lost I get. Nevermind, I decided to change a few things so as not to mix and match gets() and direct ReadConsole calls, probably best long-term anyway. Regards, Pete