How can I generate an EOF (or an ASCII 0) in a visual studio debug console? - visual-studio

I have a console-mode program running on Windows. The program calls getchar() in a loop unitl either an EOF or a 0 is returned. I'd like to enter one of the following as a test vector while running the debugger:
"abc\0" or "abc\EOF
I can't seem to consistently generate either. I tried the suggestion in this question by typing a bcCTRL-ZENTER". That returns 97,98,99,26 to my program, and then hangs on the next getchar() call.
Entering CTRL-D doesn't hlep either, getchar returns a 4 for the control char, then a newline char, and then it duplicates the line I just entered on the console. It's like VS is using the control characters as editing characters.
EDIT:
Here is a stripped down version of the code I am using. I see identical behavior in the debug console and in a command window.
#define MAXSZ 4096
int main(int argc, char **argv)
{
short int data[MAXSZ]={0}, i=0;
char c;
do {
if (i==MAXSZ) break;
c = getchar();
if (c!=EOF) data[i]=c;
} while (data[i++]!=0);
for (i=0;data[i]&&i<MAXSZ;i++)
putchar(data[i]);
}
How do I enter an EOF or an ASCII 0 in the Visual Studio debug a Windows console?

Try this one:
<Enter><Ctrl-Z><Enter>.

#Hans Passant solution works for me - should also work for OP.
1 To generate an ASCII 0, type (Ctrl+# ) or (Ctrl+2 )
2 To generate an EOF, type (Ctrl+Z Enter), but the input buffer needs to be empty. So this is typically after an (Enter), thus (Enter Ctrl+Z Enter).
But OP code has problems.
char c; // should be int ch
do {
...
c = getchar();
if (c!=EOF) data[i]=c;
} while (...);
In OP code, if the character ASCII 255 occurs , it gets assigned to a char (-1) which compares to EOF. Instead use int ch.
if (c!=EOF) data[i]=c;
// should be
if (c==EOF) break;
data[i]=c;
This prevents the code from looping forever or erring once an EOF occurs.
To enter ASCII 255
(Alt key down, num pad 2, num pad 5, num pad 5, Alt key up)

Related

MapVirtualKey returns wrong chars in MAPVK_VK_TO_CHAR mode

I trying to use MapVirtualKey[A]/[W]/[ExA]/[ExW] API to map VK_* code to character by means of its MAPVK_VK_TO_CHAR (2) mode.
I have found that it always returns 'A'..'Z' chars for 'VK_A'..'VK_Z' no matter which keyboard layout I have active.
The docs are saying that:
The uCode parameter is a virtual-key code and is translated into an
unshifted character value in the low order word of the return value.
Dead keys (diacritics) are indicated by setting the top bit of the
return value. If there is no translation, the function returns 0.
But I cannot get unshifted character value nor non-ASCII character from it.
For other buttons it works as described. And this behavior is even more annoying considering that, for example for US English keyboard layout it returns:
VK_Q (0x51) -> `Q` (U+0051 Latin Capital Letter Q)
VK_OEM_PERIOD (0xbe) -> `.` (U+002E Full Stop)
But for Russian keyboard layout it returns:
VK_Q (0x51) -> `Q` (U+0051 Latin Capital Letter Q)
^- here it should return `й` (U+0439 Cyrillic Small Letter Short I) according to docs
VK_OEM_PERIOD (0xbe) -> `ю` (U+044E Cyrillic Small Letter Yu)
How to use it properly?
MapVirtualKey has a known broken behaviour.
The docs are lying you about MAPVK_VK_TO_CHAR or 2 mode.
According to experiments and leaked Windows XP source code (in \windows\core\ntuser\kernel\xlate.c file) it contains different behaviour for 'A'..'Z' VKs (those VKs are specifically not defined in Win32 API WinUser.h header and are equivalent to 'A'..'Z' ASCII chars):
case 2:
/*
* Bogus Win3.1 functionality: despite SDK documenation, return uppercase for
* VK_A through VK_Z
*/
if ((wCode >= (WORD)'A') && (wCode <= (WORD)'Z')) {
return wCode;
}
Not sure why MS decided to pull this bug from Win 3.1 but current situation on my Windows 10 is like this.
Also some keyboard layouts can emit multiple WCHAR characters on a single key press (UTF-16 surrogate pairs or ligatures that can contain multiple Unicode code points). MapVirtualKey with MAPVK_VK_TO_CHAR is failing to return proper values for these keys too - it will return U+F002 code point in this case.
As a workaround I can recommend you to use ToUnicode[Ex] API that can do this mapping for you:
// Returns UTF-8 string
std::string GetStrFromKeyPress(uint16_t scanCode, bool isShift)
{
static BYTE keyboardState[256];
memset(keyboardState, 0, 256);
if (isShift)
{
keyboardState[VK_SHIFT] |= 0x80;
}
wchar_t chars[5] = { 0 };
const UINT vkCode = ::MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX);
// This call can produce multiple UTF-16 code points
// in case of ligatures or non-BMP Unicode chars that have hi and low surrogate
// See examples: https://kbdlayout.info/features/ligatures
int code = ::ToUnicode(vkCode, scanCode, keyboardState, chars, 4, 0);
if (code < 0)
{
// Dead key
if (chars[0] == 0 || std::iswcntrl(chars[0])) {
return {};
}
code = -code;
}
// Clear keyboard state
{
memset(keyboardState, 0, 256);
const UINT clearVkCode = VK_DECIMAL;
const UINT clearScanCode = ::MapVirtualKeyW(clearVkCode, MAPVK_VK_TO_VSC);
wchar_t tmpChars[5] = { 0 };
do {} while (::ToUnicode(clearVkCode, clearScanCode, keyboardState, tmpChars, 4, 0) < 0);
}
// Do not return control characters
if (code <= 0 || (code == 1 && std::iswcntrl(chars[0]))) {
return {};
}
return utf8::narrow(chars, code);
}
Or even better: if you have Win32 message loop - just use TranslateMessage() (that calls ToUnicode() under the hood) and then process WM_CHAR message.
PS: Same applies to GetKeyNameText API since it calls the MapVirtualKey(vk, MAPVK_VK_TO_CHAR) under the hood for keys that do not have explicit name set in keyboard layout dll (usually only non-characters do have names).

No relevant answers on the actual behavior of kbhit() on characters such as ", %, ~ in Windows 10 when keyboard and locale are US (not international)

Windows 10 with latest updates installed on a Dell XPS13. US keyboard layout and US locale selected (not international). Still a call to kbhit() or _kbhit() with specific characters such as ", ~, % does not return the key hit, at least mot until a certain amount of time (~1second) and a second character has been hit.
I try to use kbhit() because I need a non-waiting function. How can I detect correctly a keyboard hit on " or % with a single keystroke?
In Linux using a timed-out select() on stdin works great, but doesn't seem to be OK with Windows.
Thanks,
-Patrick
I finally found a solution that fits my needs and fixes the issues I have with kbhit(); code below; I hope it helps others too.
– Patrick
int getkey();
//
// int getkey(): returns the typed character at keyboard or NO_CHAR if no keyboard key was pressed.
// This is done in non-blocking mode; i.e. NO_CHAR is returned if no keyboard event is read from the
// console event queue.
// This works a lot better for me than the standard call to kbhit() which is generally used as kbhit()
// keeps some characters such as ", `, %, and tries to deal with them before returning them. Not easy
// the to follow-up what's really been typed in.
//
int getkey() {
INPUT_RECORD buf; // interested in bKeyDown event
DWORD len; // seem necessary
int ch;
ch = NO_CHAR; // default return value;
PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &buf, 1, &len);
if (len > 0) {
if (buf.EventType == KEY_EVENT && buf.Event.KeyEvent.bKeyDown) {
ch = _getche(); // set ch to input char only under right conditions
} // _getche() returns char and echoes it to console out
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); // remove consumed events
} else {
Sleep(5); // avoids too High a CPU usage when no input
}
return ch;
}
It is also possible to call ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &buf, 1, &len); rather than FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); in the code above, but for some unknown reason, it doesn't seem to reply/react as quickly and some character are missed when typing at the keyboard.

Take a 4-digit input and automatically the computer press Enter

I want that as soon as the user inputs a 4-digit number computer press enter (meaning only 4 digit input will be taken and as soon it will be taken the program will continue itself. User has no need to press enter key).
The program is written in C. I am using gcc compiler.
The getchar() function will gets a character without the need to press enter.
You can use a for loop to call the getchar() function as many times as you need it. As the loop runs, each character will be inserted in the number array.
char number[4];
for (i=0; i<4; i++) {
number[i] = getchar();
getchar();
}
We can then use the sscanf() function to convert the char array to an int!
int num;
sscanf(number, "%d", &num);

8051 sentence and word counter

I found this code below on the internet which is suppose to count the sentences on an 8051 MCU.
Can someone please explain to me what is exactly happening where there are question marks.
Any kind of help would be highly appreciated.
#include<string.h>
char code *text=" what is a program? that has, a a lot of errors! When " ;
char code *text1=" you compile. this file, uVision. reports a number of? ";
char code *text2=" problems that you! may interactively correct. " ; //Null characters are also included in array!!!
void count ( char pdata* , char pdata*);
void main (void){
char pdata Nw,Ns;
char data TextNw[2],TextNs[2];
count(&Nw, &Ns); // call subroutine
TextNw[0]=Nw/10; //?????????????????????????????????
TextNw[1]=Nw%10; //?????????????????????????????????
TextNs[0]=Ns/10; //?????????????????????????????????
TextNs[1]=Ns%10; //?????????????????????????????????
while(1);
}
void count ( char pdata *Nw, char pdata *Ns ){
unsigned char N, i, ch;
typedef enum {idle1, idle2} state; //?????????????????????????????????
state S; // begining state
P2=0x00; // pdata bank definition it must be performed first!!
*Ns=*Nw=0; // without proper start-up there is no initialisation, initialise now!!
S=idle1; // beginning state
N=strlen(text)+strlen(text1)+strlen(text2)+3; //????????????? + 3 to acount 3 Null characters!
P2=0x00; // pdata bank definition
for(i=0;i!=N;i++){
ch=text[i]; // take a caharacter from the text
switch (S)
{
case (idle1):{
if (ch==0) break; // skip NULL terminating character!
if (ch!=' '){
S=idle2;
(*Nw)++;
}
break;
}
case(idle2):{
if (ch==0) break; // skip NULL terminating character!
if((ch==' ')||(ch==','))S=idle1;
else if ((ch=='?')||(ch=='.')||(ch=='!')){
S=idle1;
(*Ns)++;
}
break;
}
}
}
}
This program does 2 things in conjunction - counts number of sentences in the text and counts the number of words in the text. Once the counting is done, the results are stored in 2-char arrays. For example, for 57 words in 3 sentences the results will be stored as this: TextNw = {'5','7'} and TextNs = {'0','3'}.
The variable N contains the full length of the text with the addition of 3 null terminating characters (one per sentence).
The algorithm simultaneously counts words and sentences. In idle1 state the counting is in word-counting mode. In idle2 state the counting is in sentence-counting mode. The modes are interchanged according to current character being read - if delimiter is encountered, the appropriate counter is increased.

Reading from Excel csv into a matrix in VC++ and some error checking?

Quick question: I have a csv file that contains 360 rows and 3 columns. Each cell or matrix entry is a type double (for example: 1.0000000, 0.9314933, 0.9866587). I was thinking the following code would get the entries:
//construct 2-d array
float CDF_inputs[360][3];
std::ifstream file("filename");
for(int row = 0; row < 360; ++row)
{
std::string line;
std::getline(file, line);
if ( !file.good() )
break;
std::stringstream iss(line);
for (int col = 0; col < 3; ++col)
{
std::string val;
std::getline(iss, val, ',');
if ( !iss.good() )
break;
std::stringstream convertor(val);
convertor >> CDF_inputs[row][col];
}
}
The file only contains doubles, no other characters (than the commas). I run the code, it builds (visual studio c++) and there are no errors. However I do not believe it is working correctly.
Is the given code correct?
How can I debug, or "print to console" either the array or an error message if the file is bad, or if the array fails to "load"?
Thanks first post for me.
I think you are learning. Well, you can place breakpoint by hitting F9 on a appropriate source code line and execute your code line-by-line by pressing F10 button. So, while debugging, you can hold mouse pointer on variables to see what they contain.
I have assumed that you are using Visual Studio.
Good Luck.

Resources