what's the difference between \r and \n?

i have a simple testing prog to enter password with just display asterisks, just like the ordinary password functions

this is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>
#include <conio.h>

int main (int argc, char * argv []) {
    char u_pwd [50];
    int count = 0;

    std::cout << "Password: ";

    while (true) {
        u_pwd[count] = _getch();
        
        if (u_pwd[count] == '\n')
            break;
        
        std::cout << "*";
        ++count;
    }

    std::cout << "your password is " << count << " long" << std::endl;
    std::cin.ignore(std::numeric_limits<int>::max(), '\n');
    std::cout << "press ENTER to close program.";
    std::cin.get();
    return 0;
}


but it doesn't break the while when ENTER pressed

https://imgur.com/db8GSsp

i've been told to use \r and it worked

why it doesn't entered to cin as '\n' but as '\r' ?

i've read frm SO:
https://stackoverflow.com/questions/3451147/difference-between-r-and-n/3451192#3451192

but it still doesn't fully answer my question
On Windows,

\n is newline (CTRL J) ASCII code 10
\r is carriage return (Enter Key or CTRL M) ASCII code 13

cin does it own processing. _getch() returns the raw, unprocessed character. You could do:

1
2
if (u_pwd[count] == '\n' || u_pwd[count] == '\r')
            break;


?inux could be different, but _getch() is for Windows.
Last edited on
seeplus wrote:

_getch() returns the raw, unprocessed character


you mean, actually, the original input from the keyboard is \r and then converted to \n by the OS?
Last edited on
Hello chipp,

Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <limits>  // <--- Added.
#include <string>
#include <conio.h>

int main(/*int argc, char * argv[]*/)  // <--- If not used you do not need it here.
{
    char u_pwd[50]{};  // <--- ALWAYS initialize your variables.
    int count = 0;

    std::cout << "Password: ";

    while (true)
    {
        char ch = _getch();

        if (ch == '\r')  // <--- Or you could use (ch = 13).
        {
            u_pwd[count] = '\0';

            break;
        }

        u_pwd[count] = ch;

        std::cout << "*";

        ++count;
    }

    std::cout << "\n\nyour password is " << count << " long" << std::endl;

    //std::cin.ignore(std::numeric_limits<int>::max(), '\n');  // <--- Not needed. There is nothing in the buffer to clear. Will wait fof something to be entered. An effictive pause.

    std::cout << "\n\n\npress ENTER to close program.";  // <--- Changed.

    std::cin.get();

    return 0;
}


Andy
Just a friendly warning: <conio.h> is not supported by all systems, such as Macintosh, which is what I use. So if you want to make sure your code is portable, use something else. I'm not saying don't use it, just if you're going to give/sell your code to clients, you want to make sure it is portable and doesn't have OS-dependent things like <conio.h>. You may already know this, in which case you can just ignore me.

Have a nice day!
max
Last edited on
you mean, actually, the original input from the keyboard is \r and then converted to \n by the OS?


Not quite. The original input is \r and is converted to \n by the CRT (C run time) - not the os. The os converts the keycode for the key pressed to the appropriate ASCII code. When you press a key, the os gets a signal that a key has been pressed and when it's been released together with its key code. This is how the OS knows that you have pressed the shift key or the ctrl key and and time how long the key(s) are pressed to generate repeat chars if held down etc. Low-level keyboard is actually quite complicated!

Also note that _getch() will not 'interpret' key strokes. So if you enter ctrl-c (which normally terminates a console program), _getch() will return 3!
Last edited on
@andy: yes, it's bcoz i used to use numeric_limits... not a prob, actually... and actually, that's not what i'm asking... i was more curious abt the escape chars...

@max: is there any function in standard C++ to replace _getch?

seeplus wrote:
Also note that _getch() will not 'interpret' key strokes. So if you enter ctrl-c (which normally terminates a console program), _getch() will return 3!

is there any references so we can find out all the original inputs?

so, after we pressed the keyboard, if the raw input not "captured" by, for example, _getch(), it will converted by CRT/OS/whatever?
Last edited on
What reference do you want? Write a small test program that just loops using _getch() and displaying its value until say ctrl_z is entered.

1
2
3
4
5
6
#include <conio.h>
#include <cstdio>

int main() {
	for (int ch {}; (ch = _getch()) != 26; printf("0x%02x ", ch));
}


It becomes interesting with the 'special keys'. Try the above and press F!, PageUp, Home, ctrl End, Alt Insert etc etc.
Last edited on
chipp,
I'm not familiar with _getch(), but I'd try getchar(), or getc(), those are in <stdio.h>.

You can also use scanf() or fscanf(), but you need to use the %d, etc to use those. They're also in <stdio.h>.

You can find all of those functions here:
https://www.cplusplus.com/reference/cstdio/
Last edited on
They aren't a direct replacement. _getch() returns when a key is pressed and doesn't wait until a CR/LF has been entered. Also, it doesn't process the obtained char (eg you can't get a ctrl_c with the get functions). AFAIK, there's no standard C/C++ replacement.

Ah. Well, what about istream::get()?
https://www.cplusplus.com/reference/istream/istream/get/?kw=cin.get

What do you mean by CR/LF?
.get() gets one char from the stream - after a line terminating char has been entered for keyboard input!

CR/LF carriage return/line feed. Enter is CR (ASCII 13) but CRT interprets this as a LF (ASCII 10) for line termination. So _getch() will give ASCII 13 for Enter but .get() will give ASCII 10.

seeplus wrote:
What reference do you want?

refs like e-books or even just a web refs is enough...

printf("0x%02x ", ch)
is this mean to print hexadecimal with width of 2 digits?

e.g.:
1
2
int c = 4;
printf ("0x%02x", c);


print output:
0x04
For a background on ASCII, see https://en.wikipedia.org/wiki/ASCII

For keyboard input with Microsoft https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input


Yes. For some stuff IMO printf() is easier to use than cout << with io manipulators. See http://www.cplusplus.com/reference/cstdio/printf/

Waiting for fmt{} in C++20........
@seeplus,
why don't you use fmt lib ?
https://github.com/fmtlib/fmt
Not allowed to. Can't use Boost either. Boo-hoo. Cry.....

I've looked at it for private use. I've also looked at the date library at https://github.com/HowardHinnant/date but again can't use for production code.
seeplus wrote:

For a background on ASCII, see https://en.wikipedia.org/wiki/ASCII

For keyboard input with Microsoft https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input


Yes. For some stuff IMO printf() is easier to use than cout << with io manipulators. See http://www.cplusplus.com/reference/cstdio/printf/

Waiting for fmt{} in C++20........
ok, thx all of you guys
Topic archived. No new replies allowed.