精华内容
下载资源
问答
  • windows中可以输入任意字符
    万次阅读
    2021-12-01 20:28:10

    A  问题:在用C语言 如何输入一串 字符串呢?

    B 解决方案: 

     1 直接用scanf("%s") 来实现

    int main()
    {
    	char str[10] = { 0 };
    	scanf("%s", str);
    
    	printf("%s", str);
    	return 0;
    }

    但是当遇到含有空格的字符串时只会记录空格前的字符而略去空格之后的字符。解决这个问题于是我们还有其他的方法。

    2.1 使用一个while循环

    int main()
    {
    	char str1[10] = { 0 };
    	int i = 0;
    	while ((str1[i] = getchar()) != '\n') {
    		++i;
    	}
    	str1[i] = '\0';
    	printf("%s", str1);
     
    	return 0;
    }

    赋值运算的结果是它的左侧运算对象,相应的,结果的类型也是左侧运算对象的类型。则while循环的退出条件就是当str1[i]=='\n'时退出,当然你可以改变'\n'成你需要的结束字符。

    2.2 使用文件结束符来结束while循环

    int main()
    {
        char str[10] = { 0 };
        int i=0;
    
        //while( ~scanf("%c",&str[i]))
        while((str[i]=getchar()) != EOF)
        {
            ++i;
        }
    
        str[i] = '\0';
        printf("%s",str);
    
        return 0;
    }
    

    windows敲ctrl+z然后按Enter键;UNIX中,用ctrl+D来输入文件结束符[EOF (-1)]。对于scanf()函数返回值为int型,如果遇到错误或者end of file,返回值为EOF,-1取反(~)得到0,判断条件为假结束循环。

    3. 使用gets()函数

    int main()
    {
    	char str[15] = { 0 };
    	gets(str);
    	printf("%s", str);
    
    	return 0;
    }

    函数从给定的输入流中读入内容,直到遇到换行符为止(注意换行符也被读进来了),然后把所读内容存入到str中去(注意不存换行符)。

    更多相关内容
  • msvcrt 的 getch() 方法 能够帮助在 Windows 下实现,其作用是获取一个按键响应并返回对应的字符。它并不在命令行回显。有如下程序段: import msvcrt print ord(msvcrt.getch()) 这里利用 ord 将获得的字符...
  • 有没有从用户输入中读取单个字符的方法?例如,他们在终端按下一个键,然后返回(类似于getch())。我知道Windows中有一个函数,但是我想要一个跨平台的函数。在Windows上,我遇到了和这个问题相同的问题。解决方案是...

    有没有从用户输入中读取单个字符的方法?例如,他们在终端按下一个键,然后返回(类似于getch())。我知道Windows中有一个函数,但是我想要一个跨平台的函数。

    在Windows上,我遇到了和这个问题相同的问题。解决方案是用msvcrt.getwch替换msvcrt.getch,如文中建议的那样。

    这里有一个链接指向一个站点,说明如何在Windows、Linux和OSX中读取单个字符:http://code.activestate.com/recipes/134892/

    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

    38class _Getch:

    """Gets a single character from standard input. Does not echo to the

    screen."""

    def __init__(self):

    try:

    self.impl = _GetchWindows()

    except ImportError:

    self.impl = _GetchUnix()

    def __call__(self): return self.impl()

    class _GetchUnix:

    def __init__(self):

    import tty, sys

    def __call__(self):

    import sys, tty, termios

    fd = sys.stdin.fileno()

    old_settings = termios.tcgetattr(fd)

    try:

    tty.setraw(sys.stdin.fileno())

    ch = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    return ch

    class _GetchWindows:

    def __init__(self):

    import msvcrt

    def __call__(self):

    import msvcrt

    return msvcrt.getch()

    getch = _Getch()

    代码似乎足够短,您可以将其包含在内,但+1用于快速找到一个好的(跨平台)答案。

    它能很好地处理非拉丁字母(如西里尔字母)吗?我有一个问题,不知道是不是我的错。

    @Ilya:看看支持非ASCII字符的getpass()是如何实现的,例如,它在Windows上使用getwch()。

    这真的很有帮助。如果不是执行return self.impl()操作,而是创建一个for循环并调用self.impl()3次,那么也可以从键盘上获得箭头键和其他转义序列。

    我不喜欢像某些if语句那样使用ImportError异常;为什么不调用platform.system()来检查操作系统?

    为什么使用它会使print语句不再正确地返回输出回车?

    @Seismoid:请求原谅通常被认为更好,请参见stackoverflow.com/questions/12265451/…

    不适用于OS X:"old_settings=termios.tcgetattr(fd)""termios.error:(25,'设备的ioctl不合适')"

    @phlya我的理解是这个代码只接受1个字节。但是,UTF-8允许用1-4字节表示单个字符。这似乎是这个解决方案的一个大问题。

    为什么这些类会覆盖__call__而不是普通方法??????????

    msvcrt.getch()不适用于Pycharm。

    这些仅仅是函数的伪类的使用是可怕的。为什么不为每一组模块和一个确定并返回要使用的函数的函数设置一个简单的函数呢?

    @德克约特这个原则在这里并不适用。首先查询操作系统不会引入竞争条件。

    想加我的2美分。在Unix实现中,当切换到tty原始模式时,输出看起来很糟糕。我建议采用以下方法来保持输出一致:old_settings = termios.tcgetattr(fd); tty.setraw(sys.stdin.fileno()); raw_settings = termios.tcgetattr(fd); raw_settings[1]=old_settings[1]; termios.tcsetattr(fd, termios.TCSADRAIN, raw_settings)。此代码保持输出标志与原始标志相同,因此当您将某些内容打印到屏幕时不会感到意外。

    不适用于MacOS。我将脚本粘贴到一个文件中,然后从第二个文件调用它——调用立即返回,而不等待控制台输入。

    ActiveStates的这个配方似乎包含了一个"posix"的小错误,它会阻止ctrl-c正常工作。请参阅下面我的答案和改进的代码。stackoverflow.com/a/48136131/404271

    1sys.stdin.read(1)

    基本上从stdin读取1个字节。

    如果您必须使用不等待的方法,您可以使用前面答案中建议的代码:

    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

    37class _Getch:

    """Gets a single character from standard input. Does not echo to the screen."""

    def __init__(self):

    try:

    self.impl = _GetchWindows()

    except ImportError:

    self.impl = _GetchUnix()

    def __call__(self): return self.impl()

    class _GetchUnix:

    def __init__(self):

    import tty, sys

    def __call__(self):

    import sys, tty, termios

    fd = sys.stdin.fileno()

    old_settings = termios.tcgetattr(fd)

    try:

    tty.setraw(sys.stdin.fileno())

    ch = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    return ch

    class _GetchWindows:

    def __init__(self):

    import msvcrt

    def __call__(self):

    import msvcrt

    return msvcrt.getch()

    getch = _Getch()

    (摘自http://code.activestate.com/recipes/134892/)

    我觉得很奇怪sys.stdin.read(1)等待一个,lol。不过,谢谢您的提交。

    一个字符还是一个字节?这不一样。

    @Evan,这是因为默认情况下,python处于行缓冲模式。

    请注意,此代码阻止您使用^C或^D!

    @evanfosmark:不一定是sys.stdin.read(1)等待,而是终端程序决定何时将其他字符发送到程序,直到它看到'-否则,您如何能够按backspace并更正您键入的内容?(严肃的回答是-教python程序实现行控制、保留缓冲区、处理退格,但是这是一个不同的世界,当你仅仅"读取字符"时,你可能不想去购买它,并且可能会使你的行处理不同于系统上的所有其他程序。)

    我不喜欢像某些if语句那样使用ImportError异常;为什么不调用platform.system()来检查操作系统?

    地震震颤

    两个答案中逐字引用的ActiveState配方设计过度。可以归结为:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23def _find_getch():

    try:

    import termios

    except ImportError:

    # Non-POSIX. Return msvcrt's (Windows') getch.

    import msvcrt

    return msvcrt.getch

    # POSIX system. Create and return a getch that manipulates the tty.

    import sys, tty

    def _getch():

    fd = sys.stdin.fileno()

    old_settings = termios.tcgetattr(fd)

    try:

    tty.setraw(fd)

    ch = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    return ch

    return _getch

    getch = _find_getch()

    另一个值得尝试的是readchar库,它部分基于其他答案中提到的activestate配方。

    安装:

    1pip install readchar

    用途:

    1

    2

    3

    4

    5import readchar

    print("Reading a char:")

    print(repr(readchar.readchar()))

    print("Reading a key:")

    print(repr(readchar.readkey()))

    在Windows和Linux上测试了python 2.7。

    在Windows上,仅支持映射到字母或ASCII控制代码的键(backspace、enter、esc、t、ctrl+letter)。在GNU/Linux上(可能取决于确切的终端?)您还可以获得insert、elete、pg up、pg dn、home、end和f nakbd密钥…但是,将这些特殊键与esc分离时会遇到一些问题。

    警告:就像大多数(全部)一样?在这里,信号键CtrL+CbaBd、CtrL+DbaBbbd和CtrL+z被捕获并返回(分别为'\x03'、'\x04'和'\x1a';您的程序可能很难中止。

    也可以在Linux上使用python 3。比getch好得多,因为readchar允许在等待键时(通过线程或异步)打印到stdout。

    在kubuntu linux上测试过,这是一个非常完美的pythonic。谢谢您!

    在Win10+python 3.5上测试:错误:根:"in"要求字符串作为左操作数,而不是字节回溯(最近调用的最后一个):file"..main.py",第184行,包装结果=func(*args,**kwargs)file"c:githubpython demodemodayhello.py",第41行,在readch中,例如print(readchar.readchar())file"c:usersipcjsappdatalocalprogramspythonpython35libs‌&误8203;ite packages

    eadcha‌&误8203;r

    eadchar_windows.p‌&误8203;y",第14行,位于readchar中,而ch位于x00xe0":typeerror:"in"需要字符串作为左操作数,而不是字节

    @请向维护人员报告该错误

    这是最好的答案。为VS C++库添加一个依赖性只是为了这个功能是疯狂的。

    另一种方法:

    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

    26import os

    import sys

    import termios

    import fcntl

    def getch():

    fd = sys.stdin.fileno()

    oldterm = termios.tcgetattr(fd)

    newattr = termios.tcgetattr(fd)

    newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO

    termios.tcsetattr(fd, termios.TCSANOW, newattr)

    oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)

    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

    try:

    while 1:

    try:

    c = sys.stdin.read(1)

    break

    except IOError: pass

    finally:

    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)

    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

    return c

    从这个博客文章。

    似乎对我不起作用-调用后立即返回空字符串。在使用python 3.6的Linux上。

    @如果要阻止(等待输入),请删除| os.O_NONBLOCK。否则,你可以把它放在一个循环中(最好在循环中睡一会儿以避免旋转)。

    我认为在这一点上它变得非常笨拙,在不同的平台上调试是一个很大的混乱。

    如果你在做比这更复杂的事情,并且需要视觉效果,或者如果你要使用终端的话,你最好使用类似于pyglet,pygame,cocos2d的东西。

    诅咒是标准的:http://docs.python.org/library/curses.html

    我强烈反对这一点。要使用诅咒,您必须初始化清除屏幕的终端。如果用户只想使用curses来获取用户输入而不使用,则这是不需要的行为。

    如果按下ctrl+c或ctrl+d,则基于此处的代码将正确引发键盘中断和eoferror。

    应该在Windows和Linux上工作。可以从原始源获得OS X版本。

    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

    41

    42

    43

    44

    45class _Getch:

    """Gets a single character from standard input. Does not echo to the screen."""

    def __init__(self):

    try:

    self.impl = _GetchWindows()

    except ImportError:

    self.impl = _GetchUnix()

    def __call__(self):

    char = self.impl()

    if char == '\x03':

    raise KeyboardInterrupt

    elif char == '\x04':

    raise EOFError

    return char

    class _GetchUnix:

    def __init__(self):

    import tty

    import sys

    def __call__(self):

    import sys

    import tty

    import termios

    fd = sys.stdin.fileno()

    old_settings = termios.tcgetattr(fd)

    try:

    tty.setraw(sys.stdin.fileno())

    ch = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    return ch

    class _GetchWindows:

    def __init__(self):

    import msvcrt

    def __call__(self):

    import msvcrt

    return msvcrt.getch()

    getch = _Getch()

    此代码等待。

    (目前)排名靠前的答案(带有ActiveState代码)过于复杂。当一个函数足够时,我看不出使用类的理由。下面是两个实现,它们完成了相同的事情,但具有更可读的代码。

    这两种实现:

    在python 2或python 3中工作得很好

    在Windows、OSX和Linux上工作

    只读取一个字节(即,它们不等待换行)

    不依赖任何外部库

    是独立的(函数定义之外没有代码)

    版本1:可读简单

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20def getChar():

    try:

    # for Windows-based systems

    import msvcrt # If successful, we are on Windows

    return msvcrt.getch()

    except ImportError:

    # for POSIX-based systems (with termios & tty support)

    import tty, sys, termios # raises ImportError if unsupported

    fd = sys.stdin.fileno()

    oldSettings = termios.tcgetattr(fd)

    try:

    tty.setcbreak(fd)

    answer = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, oldSettings)

    return answer

    版本2:避免重复导入和异常处理:

    [编辑]我错过了ActiveState代码的一个优势。如果您计划多次读取字符,那么该代码可以避免在类似Unix的系统上重复Windows导入和importError异常处理的成本(可以忽略不计)。虽然您可能更关注代码的可读性,而不是忽略不计的优化,但这里有一个替代方案(它类似于Louis的答案,但getchar()是独立的),它的功能与ActiveState代码相同,并且更具可读性:

    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

    27def getChar():

    # figure out which function to use once, and store it in _func

    if"_func" not in getChar.__dict__:

    try:

    # for Windows-based systems

    import msvcrt # If successful, we are on Windows

    getChar._func=msvcrt.getch

    except ImportError:

    # for POSIX-based systems (with termios & tty support)

    import tty, sys, termios # raises ImportError if unsupported

    def _ttyRead():

    fd = sys.stdin.fileno()

    oldSettings = termios.tcgetattr(fd)

    try:

    tty.setcbreak(fd)

    answer = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, oldSettings)

    return answer

    getChar._func=_ttyRead

    return getChar._func()

    执行上述getchar()版本的示例代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11from __future__ import print_function # put at top of file if using Python 2

    # Example of a prompt for one character of input

    promptStr ="Please give me a character:"

    responseStr ="Thank you for giving me a '{}'."

    print(promptStr, end="

    >")

    answer = getChar()

    print("

    ")

    print(responseStr.format(answer))

    我在打印消息的同时等待一个键(多线程)时遇到了tty.setraw()的问题。长话短说,我发现使用tty.setcbreak()可以得到一个字符,而不会破坏其他所有正常的内容。这个答案说来话长

    很好,我希望有一种更干净的方法

    这可能是上下文管理器的用例。除了Windows操作系统的允许之外,我的建议是:

    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#!/usr/bin/env python3

    # file: 'readchar.py'

    """

    Implementation of a way to get a single character of input

    without waiting for the user to hit .

    (OS is Linux, Ubuntu 14.04)

    """

    import tty, sys, termios

    class ReadChar():

    def __enter__(self):

    self.fd = sys.stdin.fileno()

    self.old_settings = termios.tcgetattr(self.fd)

    tty.setraw(sys.stdin.fileno())

    return sys.stdin.read(1)

    def __exit__(self, type, value, traceback):

    termios.tcsetattr(self.fd, termios.TCSADRAIN, self.old_settings)

    def test():

    while True:

    with ReadChar() as rc:

    char = rc

    if ord(char) <= 32:

    print("You entered character with ordinal {}."\

    .format(ord(char)))

    else:

    print("You entered character '{}'."\

    .format(char))

    if char in"^C^D":

    sys.exit()

    if __name__ =="__main__":

    test()

    您还可以在__enter__中返回self,并使用返回sys.stdin.read(1)的read方法,然后在一个上下文中读取多个字符。

    这里的答案很有信息性,但是我也希望有一种方法可以异步地获取按键,并在单独的事件中触发按键,所有这些都是线程安全的跨平台方式。Pygame对我来说也太臃肿了。所以我做了以下内容(在python 2.7中,但我怀疑它很容易移植),我想在这里分享一下,以防它对其他人有用。我把它存储在一个名为keypress.py的文件中。好的。

    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

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    169

    170

    171

    172

    173

    174

    175

    176

    177

    178

    179

    180

    181

    182

    183

    184

    185

    186

    187

    188

    189

    190

    191

    192

    193

    194

    195

    196

    197

    198

    199

    200

    201

    202

    203

    204

    205

    206

    207

    208

    209

    210

    211

    212

    213

    214

    215

    216

    217

    218

    219

    220

    221

    222

    223

    224

    225

    226

    227

    228

    229

    230

    231

    232

    233

    234

    235

    236

    237

    238

    239

    240

    241

    242

    243

    244

    245

    246

    247

    248

    249

    250

    251

    252

    253

    254

    255

    256

    257

    258

    259

    260

    261

    262

    263

    264

    265

    266

    267

    268

    269

    270

    271

    272

    273

    274

    275

    276

    277

    278

    279

    280

    281

    282

    283

    284

    285

    286

    287

    288

    289

    290

    291

    292

    293

    294

    295

    296

    297

    298

    299

    300

    301

    302

    303

    304

    305

    306

    307

    308

    309

    310

    311

    312

    313

    314

    315

    316

    317

    318

    319

    320

    321

    322

    323

    324

    325

    326

    327

    328

    329

    330

    331

    332

    333

    334

    335

    336

    337

    338

    339

    340

    341

    342

    343

    344

    345

    346

    347

    348

    349

    350

    351

    352

    353

    354

    355

    356

    357

    358

    359

    360

    361

    362

    363

    364

    365

    366

    367

    368

    369

    370

    371

    372

    373

    374

    375

    376

    377

    378

    379

    380

    381

    382

    383

    384

    385

    386

    387

    388

    389

    390

    391

    392

    393

    394

    395class _Getch:

    """Gets a single character from standard input. Does not echo to the

    screen. From http://code.activestate.com/recipes/134892/"""

    def __init__(self):

    try:

    self.impl = _GetchWindows()

    except ImportError:

    try:

    self.impl = _GetchMacCarbon()

    except(AttributeError, ImportError):

    self.impl = _GetchUnix()

    def __call__(self): return self.impl()

    class _GetchUnix:

    def __init__(self):

    import tty, sys, termios # import termios now or else you'll get the Unix version on the Mac

    def __call__(self):

    import sys, tty, termios

    fd = sys.stdin.fileno()

    old_settings = termios.tcgetattr(fd)

    try:

    tty.setraw(sys.stdin.fileno())

    ch = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    return ch

    class _GetchWindows:

    def __init__(self):

    import msvcrt

    def __call__(self):

    import msvcrt

    return msvcrt.getch()

    class _GetchMacCarbon:

    """

    A function which returns the current ASCII key that is down;

    if no ASCII key is down, the null string is returned. The

    page http://www.mactech.com/macintosh-c/chap02-1.html was

    very helpful in figuring out how to do this.

    """

    def __init__(self):

    import Carbon

    Carbon.Evt #see if it has this (in Unix, it doesn't)

    def __call__(self):

    import Carbon

    if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask

    return ''

    else:

    #

    # The event contains the following info:

    # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]

    #

    # The message (msg) contains the ASCII char which is

    # extracted with the 0x000000FF charCodeMask; this

    # number is converted to an ASCII character with chr() and

    # returned

    #

    (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]

    return chr(msg & 0x000000FF)

    import threading

    # From https://stackoverflow.com/a/2022629/2924421

    class Event(list):

    def __call__(self, *args, **kwargs):

    for f in self:

    f(*args, **kwargs)

    def __repr__(self):

    return"Event(%s)" % list.__repr__(self)

    def getKey():

    inkey = _Getch()

    import sys

    for i in xrange(sys.maxint):

    k=inkey()

    if k<>'':break

    return k

    class KeyCallbackFunction():

    callbackParam = None

    actualFunction = None

    def __init__(self, actualFunction, callbackParam):

    self.actualFunction = actualFunction

    self.callbackParam = callbackParam

    def doCallback(self, inputKey):

    if not self.actualFunction is None:

    if self.callbackParam is None:

    callbackFunctionThread = threading.Thread(target=self.actualFunction, args=(inputKey,))

    else:

    callbackFunctionThread = threading.Thread(target=self.actualFunction, args=(inputKey,self.callbackParam))

    callbackFunctionThread.daemon = True

    callbackFunctionThread.start()

    class KeyCapture():

    gotKeyLock = threading.Lock()

    gotKeys = []

    gotKeyEvent = threading.Event()

    keyBlockingSetKeyLock = threading.Lock()

    addingEventsLock = threading.Lock()

    keyReceiveEvents = Event()

    keysGotLock = threading.Lock()

    keysGot = []

    keyBlockingKeyLockLossy = threading.Lock()

    keyBlockingKeyLossy = None

    keyBlockingEventLossy = threading.Event()

    keysBlockingGotLock = threading.Lock()

    keysBlockingGot = []

    keyBlockingGotEvent = threading.Event()

    wantToStopLock = threading.Lock()

    wantToStop = False

    stoppedLock = threading.Lock()

    stopped = True

    isRunningEvent = False

    getKeyThread = None

    keyFunction = None

    keyArgs = None

    # Begin capturing keys. A seperate thread is launched that

    # captures key presses, and then these can be received via get,

    # getAsync, and adding an event via addEvent. Note that this

    # will prevent the system to accept keys as normal (say, if

    # you are in a python shell) because it overrides that key

    # capturing behavior.

    # If you start capture when it's already been started, a

    # InterruptedError("Keys are still being captured")

    # will be thrown

    # Note that get(), getAsync() and events are independent, so if a key is pressed:

    #

    # 1: Any calls to get() that are waiting, with lossy on, will return

    # that key

    # 2: It will be stored in the queue of get keys, so that get() with lossy

    # off will return the oldest key pressed not returned by get() yet.

    # 3: All events will be fired with that key as their input

    # 4: It will be stored in the list of getAsync() keys, where that list

    # will be returned and set to empty list on the next call to getAsync().

    # get() call with it, aand add it to the getAsync() list.

    def startCapture(self, keyFunction=None, args=None):

    # Make sure we aren't already capturing keys

    self.stoppedLock.acquire()

    if not self.stopped:

    self.stoppedLock.release()

    raise InterruptedError("Keys are still being captured")

    return

    self.stopped = False

    self.stoppedLock.release()

    # If we have captured before, we need to allow the get() calls to actually

    # wait for key presses now by clearing the event

    if self.keyBlockingEventLossy.is_set():

    self.keyBlockingEventLossy.clear()

    # Have one function that we call every time a key is captured, intended for stopping capture

    # as desired

    self.keyFunction = keyFunction

    self.keyArgs = args

    # Begin capturing keys (in a seperate thread)

    self.getKeyThread = threading.Thread(target=self._threadProcessKeyPresses)

    self.getKeyThread.daemon = True

    self.getKeyThread.start()

    # Process key captures (in a seperate thread)

    self.getKeyThread = threading.Thread(target=self._threadStoreKeyPresses)

    self.getKeyThread.daemon = True

    self.getKeyThread.start()

    def capturing(self):

    self.stoppedLock.acquire()

    isCapturing = not self.stopped

    self.stoppedLock.release()

    return isCapturing

    # Stops the thread that is capturing keys on the first opporunity

    # has to do so. It usually can't stop immediately because getting a key

    # is a blocking process, so this will probably stop capturing after the

    # next key is pressed.

    #

    # However, Sometimes if you call stopCapture it will stop before starting capturing the

    # next key, due to multithreading race conditions. So if you want to stop capturing

    # reliably, call stopCapture in a function added via addEvent. Then you are

    # guaranteed that capturing will stop immediately after the rest of the callback

    # functions are called (before starting to capture the next key).

    def stopCapture(self):

    self.wantToStopLock.acquire()

    self.wantToStop = True

    self.wantToStopLock.release()

    # Takes in a function that will be called every time a key is pressed (with that

    # key passed in as the first paramater in that function)

    def addEvent(self, keyPressEventFunction, args=None):

    self.addingEventsLock.acquire()

    callbackHolder = KeyCallbackFunction(keyPressEventFunction, args)

    self.keyReceiveEvents.append(callbackHolder.doCallback)

    self.addingEventsLock.release()

    def clearEvents(self):

    self.addingEventsLock.acquire()

    self.keyReceiveEvents = Event()

    self.addingEventsLock.release()

    # Gets a key captured by this KeyCapture, blocking until a key is pressed.

    # There is an optional lossy paramater:

    # If True all keys before this call are ignored, and the next pressed key

    # will be returned.

    # If False this will return the oldest key captured that hasn't

    # been returned by get yet. False is the default.

    def get(self, lossy=False):

    if lossy:

    # Wait for the next key to be pressed

    self.keyBlockingEventLossy.wait()

    self.keyBlockingKeyLockLossy.acquire()

    keyReceived = self.keyBlockingKeyLossy

    self.keyBlockingKeyLockLossy.release()

    return keyReceived

    else:

    while True:

    # Wait until a key is pressed

    self.keyBlockingGotEvent.wait()

    # Get the key pressed

    readKey = None

    self.keysBlockingGotLock.acquire()

    # Get a key if it exists

    if len(self.keysBlockingGot) != 0:

    readKey = self.keysBlockingGot.pop(0)

    # If we got the last one, tell us to wait

    if len(self.keysBlockingGot) == 0:

    self.keyBlockingGotEvent.clear()

    self.keysBlockingGotLock.release()

    # Process the key (if it actually exists)

    if not readKey is None:

    return readKey

    # Exit if we are stopping

    self.wantToStopLock.acquire()

    if self.wantToStop:

    self.wantToStopLock.release()

    return None

    self.wantToStopLock.release()

    def clearGetList(self):

    self.keysBlockingGotLock.acquire()

    self.keysBlockingGot = []

    self.keysBlockingGotLock.release()

    # Gets a list of all keys pressed since the last call to getAsync, in order

    # from first pressed, second pressed, .., most recent pressed

    def getAsync(self):

    self.keysGotLock.acquire();

    keysPressedList = list(self.keysGot)

    self.keysGot = []

    self.keysGotLock.release()

    return keysPressedList

    def clearAsyncList(self):

    self.keysGotLock.acquire();

    self.keysGot = []

    self.keysGotLock.release();

    def _processKey(self, readKey):

    # Append to list for GetKeyAsync

    self.keysGotLock.acquire()

    self.keysGot.append(readKey)

    self.keysGotLock.release()

    # Call lossy blocking key events

    self.keyBlockingKeyLockLossy.acquire()

    self.keyBlockingKeyLossy = readKey

    self.keyBlockingEventLossy.set()

    self.keyBlockingEventLossy.clear()

    self.keyBlockingKeyLockLossy.release()

    # Call non-lossy blocking key events

    self.keysBlockingGotLock.acquire()

    self.keysBlockingGot.append(readKey)

    if len(self.keysBlockingGot) == 1:

    self.keyBlockingGotEvent.set()

    self.keysBlockingGotLock.release()

    # Call events added by AddEvent

    self.addingEventsLock.acquire()

    self.keyReceiveEvents(readKey)

    self.addingEventsLock.release()

    def _threadProcessKeyPresses(self):

    while True:

    # Wait until a key is pressed

    self.gotKeyEvent.wait()

    # Get the key pressed

    readKey = None

    self.gotKeyLock.acquire()

    # Get a key if it exists

    if len(self.gotKeys) != 0:

    readKey = self.gotKeys.pop(0)

    # If we got the last one, tell us to wait

    if len(self.gotKeys) == 0:

    self.gotKeyEvent.clear()

    self.gotKeyLock.release()

    # Process the key (if it actually exists)

    if not readKey is None:

    self._processKey(readKey)

    # Exit if we are stopping

    self.wantToStopLock.acquire()

    if self.wantToStop:

    self.wantToStopLock.release()

    break

    self.wantToStopLock.release()

    def _threadStoreKeyPresses(self):

    while True:

    # Get a key

    readKey = getKey()

    # Run the potential shut down function

    if not self.keyFunction is None:

    self.keyFunction(readKey, self.keyArgs)

    # Add the key to the list of pressed keys

    self.gotKeyLock.acquire()

    self.gotKeys.append(readKey)

    if len(self.gotKeys) == 1:

    self.gotKeyEvent.set()

    self.gotKeyLock.release()

    # Exit if we are stopping

    self.wantToStopLock.acquire()

    if self.wantToStop:

    self.wantToStopLock.release()

    self.gotKeyEvent.set()

    break

    self.wantToStopLock.release()

    # If we have reached here we stopped capturing

    # All we need to do to clean up is ensure that

    # all the calls to .get() now return None.

    # To ensure no calls are stuck never returning,

    # we will leave the event set so any tasks waiting

    # for it immediately exit. This will be unset upon

    # starting key capturing again.

    self.stoppedLock.acquire()

    # We also need to set this to True so we can start up

    # capturing again.

    self.stopped = True

    self.stopped = True

    self.keyBlockingKeyLockLossy.acquire()

    self.keyBlockingKeyLossy = None

    self.keyBlockingEventLossy.set()

    self.keyBlockingKeyLockLossy.release()

    self.keysBlockingGotLock.acquire()

    self.keyBlockingGotEvent.set()

    self.keysBlockingGotLock.release()

    self.stoppedLock.release()

    其思想是,您可以简单地调用keyPress.getKey(),它将从键盘读取一个键,然后返回它。好的。

    如果你想要更多的东西,我做了一个KeyCapture物体。您可以通过类似于keys = keyPress.KeyCapture()的方式创建一个。好的。

    然后你可以做三件事:好的。

    addEvent(functionName)接受任何接受一个参数的函数。然后,每次按下一个键时,这个函数都会以该键的字符串作为输入来调用。这些是在一个单独的线程中运行的,因此您可以阻塞它们中的所有内容,并且它不会破坏keycapturer的功能,也不会延迟其他事件。好的。

    get()以与以前相同的阻塞方式返回密钥。现在需要这样做,因为密钥现在是通过KeyCapture对象捕获的,所以keyPress.getKey()会与该行为冲突,并且它们都会丢失一些密钥,因为一次只能捕获一个密钥。另外,假设用户按"a",然后按"b",你称之为get(),用户按"c"。该get()调用将立即返回"a",如果您再次调用它,它将返回"b",然后返回"c"。如果您再次调用它,它将一直阻塞,直到按下另一个键。这可以确保您不会错过任何键,如果需要的话,以阻塞的方式。所以这和之前的keyPress.getKey()有点不同好的。

    如果你想让getKey()返回,get(lossy=True)就像get()一样,只是在调用get()之后,它只返回按下的键。所以在上面的例子中,get()会一直阻塞,直到用户按"c",然后如果您再次调用它,它会阻塞,直到另一个键被按下。好的。

    getAsync()有点不同。它是为做大量处理的事情而设计的,然后偶尔回来检查哪些键被按下。因此,getAsync()返回自上次调用getAsync()以来按下的所有键的列表,从按下的最旧键到最近按下的键。它也不会阻塞,这意味着如果自上次调用getAsync()以来没有按下任何键,则返回空的[]。好的。

    要真正开始捕获密钥,您需要使用上面制作的keys对象调用keys.startCapture()。startCapture是非阻塞的,只需启动一个只记录按键的线程,以及另一个处理按键的线程。有两个线程来确保记录按键的线程不会丢失任何键。好的。

    如果要停止捕获密钥,可以调用keys.stopCapture(),它将停止捕获密钥。但是,由于捕获密钥是一个阻塞操作,线程捕获密钥可能在调用stopCapture()之后再捕获一个密钥。好的。

    为了防止出现这种情况,可以将可选参数传入函数的startCapture(functionName, args)中,该函数执行类似于检查键是否等于"c",然后退出的操作。很重要的一点是,这个功能以前很少做,例如,在这里睡觉会导致我们错过钥匙。好的。

    但是,如果在该函数中调用stopCapture(),则将立即停止密钥捕获,而不再尝试捕获,并且将立即返回所有get()调用,如果尚未按下任何键,则不返回任何调用。好的。

    另外,由于get()和getAsync()存储所有以前按过的键(直到您检索它们),您可以调用clearGetList()和clearAsyncList()来忘记以前按过的键。好的。

    请注意,get()、getAsync()和事件是独立的,因此如果按下某个键:1。一个正在等待的、有损接通的get()呼叫将返回。那把钥匙。其他等待呼叫(如果有)将继续等待。2。该密钥将存储在GET密钥队列中,这样,在关闭lossy的情况下,get()将返回尚未由get()返回的最旧密钥。三。所有事件都将以该键作为输入进行激发4。该键将存储在getAsync()键列表中,在该列表中,将返回该lis twill,并在下次调用getAsync()时设置为空列表。好的。

    如果所有这些都太多,下面是一个示例用例:好的。

    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

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76import keyPress

    import time

    import threading

    def KeyPressed(k, printLock):

    printLock.acquire()

    print"Event:" + k

    printLock.release()

    time.sleep(4)

    printLock.acquire()

    print"Event after delay:" + k

    printLock.release()

    def GetKeyBlocking(keys, printLock):

    while keys.capturing():

    keyReceived = keys.get()

    time.sleep(1)

    printLock.acquire()

    if not keyReceived is None:

    print"Block" + keyReceived

    else:

    print"Block None"

    printLock.release()

    def GetKeyBlockingLossy(keys, printLock):

    while keys.capturing():

    keyReceived = keys.get(lossy=True)

    time.sleep(1)

    printLock.acquire()

    if not keyReceived is None:

    print"Lossy:" + keyReceived

    else:

    print"Lossy: None"

    printLock.release()

    def CheckToClose(k, (keys, printLock)):

    printLock.acquire()

    print"Close:" + k

    printLock.release()

    if k =="c":

    keys.stopCapture()

    printLock = threading.Lock()

    print"Press a key:"

    print"You pressed:" + keyPress.getKey()

    print""

    keys = keyPress.KeyCapture()

    keys.addEvent(KeyPressed, printLock)

    print"Starting capture"

    keys.startCapture(CheckToClose, (keys, printLock))

    getKeyBlockingThread = threading.Thread(target=GetKeyBlocking, args=(keys, printLock))

    getKeyBlockingThread.daemon = True

    getKeyBlockingThread.start()

    getKeyBlockingThreadLossy = threading.Thread(target=GetKeyBlockingLossy, args=(keys, printLock))

    getKeyBlockingThreadLossy.daemon = True

    getKeyBlockingThreadLossy.start()

    while keys.capturing():

    keysPressed = keys.getAsync()

    printLock.acquire()

    if keysPressed != []:

    print"Async:" + str(keysPressed)

    printLock.release()

    time.sleep(1)

    print"done capturing"

    从我做的简单测试来看,它对我来说很好,但是如果我错过了什么,我也会很高兴地接受其他人的反馈。好的。

    我也把这个贴在这里了。好的。好啊。

    其中一个答案中的注释提到了cbreak模式,这对Unix实现很重要,因为您通常不希望getchar使用^c(KeyboardError)(与大多数其他答案一样,当您将终端设置为原始模式时会使用)。

    另一个重要的细节是,如果您希望读取一个字符而不是一个字节,那么应该从输入流中读取4个字节,因为这是一个字符在UTF-8(python 3+)中所包含的最大字节数。仅读取一个字节将对多字节字符(如键盘箭头)产生意外结果。

    以下是我为Unix更改的实现:

    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

    31import contextlib

    import os

    import sys

    import termios

    import tty

    _MAX_CHARACTER_BYTE_LENGTH = 4

    @contextlib.contextmanager

    def _tty_reset(file_descriptor):

    """

    A context manager that saves the tty flags of a file descriptor upon

    entering and restores them upon exiting.

    """

    old_settings = termios.tcgetattr(file_descriptor)

    try:

    yield

    finally:

    termios.tcsetattr(file_descriptor, termios.TCSADRAIN, old_settings)

    def get_character(file=sys.stdin):

    """

    Read a single character from the given input stream (defaults to sys.stdin).

    """

    file_descriptor = file.fileno()

    with _tty_reset(file_descriptor):

    tty.setcbreak(file_descriptor)

    return os.read(file_descriptor, _MAX_CHARACTER_BYTE_LENGTH)

    尝试使用:http://home.wlu.edu/~levys/software/kbhit.py它是非阻塞的(这意味着你可以有一个while循环,在不停止的情况下检测到一个按键)和跨平台的。

    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

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92import os

    # Windows

    if os.name == 'nt':

    import msvcrt

    # Posix (Linux, OS X)

    else:

    import sys

    import termios

    import atexit

    from select import select

    class KBHit:

    def __init__(self):

    '''Creates a KBHit object that you can call to do various keyboard things.'''

    if os.name == 'nt':

    pass

    else:

    # Save the terminal settings

    self.fd = sys.stdin.fileno()

    self.new_term = termios.tcgetattr(self.fd)

    self.old_term = termios.tcgetattr(self.fd)

    # New terminal setting unbuffered

    self.new_term[3] = (self.new_term[3] & ~termios.ICANON & ~termios.ECHO)

    termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.new_term)

    # Support normal-terminal reset at exit

    atexit.register(self.set_normal_term)

    def set_normal_term(self):

    ''' Resets to normal terminal. On Windows this is a no-op.

    '''

    if os.name == 'nt':

    pass

    else:

    termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term)

    def getch(self):

    ''' Returns a keyboard character after kbhit() has been called.

    Should not be called in the same program as getarrow().

    '''

    s = ''

    if os.name == 'nt':

    return msvcrt.getch().decode('utf-8')

    else:

    return sys.stdin.read(1)

    def getarrow(self):

    ''' Returns an arrow-key code after kbhit() has been called. Codes are

    0 : up

    1 : right

    2 : down

    3 : left

    Should not be called in the same program as getch().

    '''

    if os.name == 'nt':

    msvcrt.getch() # skip 0xE0

    c = msvcrt.getch()

    vals = [72, 77, 80, 75]

    else:

    c = sys.stdin.read(3)[2]

    vals = [65, 67, 66, 68]

    return vals.index(ord(c.decode('utf-8')))

    def kbhit(self):

    ''' Returns True if keyboard character was hit, False otherwise.

    '''

    if os.name == 'nt':

    return msvcrt.kbhit()

    else:

    dr,dw,de = select([sys.stdin], [], [], 0)

    return dr != []

    使用此方法的示例:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10import kbhit

    kb = kbhit.KBHit()

    while(True):

    print("Key not pressed") #Do something

    if kb.kbhit(): #If a key is pressed:

    k_in = kb.getch() #Detect what key was pressed

    print("You pressed", k_in,"!") #Do something

    kb.set_normal_term()

    或者可以使用PYPI中的getch模块。但这会阻塞while循环

    这是非阻塞的,读取一个键并将其存储在keypress.key中。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17import Tkinter as tk

    class Keypress:

    def __init__(self):

    self.root = tk.Tk()

    self.root.geometry('300x200')

    self.root.bind('', self.onKeyPress)

    def onKeyPress(self, event):

    self.key = event.char

    def __eq__(self, other):

    return self.key == other

    def __str__(self):

    return self.key

    在您的程序中

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10keypress = Keypress()

    while something:

    do something

    if keypress == 'c':

    break

    elif keypress == 'i':

    print('info')

    else:

    print("i dont understand %s" % keypress)

    这对命令行应用程序有效吗?

    是@thorsummer

    @thorsummoner:这个代码有很多问题——所以不,它不能用于命令行应用程序。

    它为命令行应用程序运行,前提是Windows管理器正在运行。

    所以基本上它不适用于命令行应用程序…

    不,它不会在无头操作系统中运行。但它确实在命令行窗口中运行。

    用Pygame试试这个:

    1

    2

    3

    4

    5

    6

    7

    8import pygame

    pygame.init() // eliminate error, pygame.error: video system not initialized

    keys = pygame.key.get_pressed()

    if keys[pygame.K_SPACE]:

    d ="space key"

    print"You pressed the", d,"."

    这是一个很好的想法,但在命令行上不起作用:pygame.error: video system not initialized

    ActiveState的配方似乎包含一个"posix"系统的小错误,它可以防止Ctrl-C中断(我使用的是mac)。如果我在脚本中放入以下代码:

    1

    2while(True):

    print(getch())

    我永远无法用Ctrl-C终止脚本,我必须杀死终端才能逃脱。

    我相信下面这句话是原因,而且太残忍了:

    1tty.setraw(sys.stdin.fileno())

    除此之外,并不需要tty包,termios包就足够了。

    下面是适用于我的改进代码(Ctrl-C将中断),额外的getche函数将在键入时回送字符:

    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

    31if sys.platform == 'win32':

    import msvcrt

    getch = msvcrt.getch

    getche = msvcrt.getche

    else:

    import sys

    import termios

    def __gen_ch_getter(echo):

    def __fun():

    fd = sys.stdin.fileno()

    oldattr = termios.tcgetattr(fd)

    newattr = oldattr[:]

    try:

    if echo:

    # disable ctrl character printing, otherwise, backspace will be printed as"^?"

    lflag = ~(termios.ICANON | termios.ECHOCTL)

    else:

    lflag = ~(termios.ICANON | termios.ECHO)

    newattr[3] &= lflag

    termios.tcsetattr(fd, termios.TCSADRAIN, newattr)

    ch = sys.stdin.read(1)

    if echo and ord(ch) == 127: # backspace

    # emulate backspace erasing

    # https://stackoverflow.com/a/47962872/404271

    sys.stdout.write('\b \b')

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, oldattr)

    return ch

    return __fun

    getch = __gen_ch_getter(False)

    getche = __gen_ch_getter(True)

    参考文献:

    https://pypi.python.org/pypi/getch网站

    python中的curses包只需几条语句就可以用于从终端输入字符,进入"原始"模式。Curses的主要用途是接管屏幕进行输出,这可能不是您想要的。此代码段使用print()语句,这是可用的,但您必须知道curses是如何更改附加到输出的行尾的。

    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#!/usr/bin/python3

    # Demo of single char terminal input in raw mode with the curses package.

    import sys, curses

    def run_one_char(dummy):

    'Run until a carriage return is entered'

    char = ' '

    print('Welcome to curses', flush=True)

    while ord(char) != 13:

    char = one_char()

    def one_char():

    'Read one character from the keyboard'

    print('

    ? ', flush= True, end = '')

    ## A blocking single char read in raw mode.

    char = sys.stdin.read(1)

    print('You entered %s

    ' % char)

    return char

    ## Must init curses before calling any functions

    curses.initscr()

    ## To make sure the terminal returns to its initial settings,

    ## and to set raw mode and guarantee cleanup on exit.

    curses.wrapper(run_one_char)

    print('Curses be gone!')

    如果我做一些复杂的事情,我会用诅咒来读钥匙。但很多时候我只需要一个简单的python 3脚本,它使用标准库,可以读取箭头键,所以我这样做:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22import sys, termios, tty

    key_Enter = 13

    key_Esc = 27

    key_Up = '\033[A'

    key_Dn = '\033[B'

    key_Rt = '\033[C'

    key_Lt = '\033[D'

    fdInput = sys.stdin.fileno()

    termAttr = termios.tcgetattr(0)

    def getch():

    tty.setraw(fdInput)

    ch = sys.stdin.buffer.raw.read(4).decode(sys.stdin.encoding)

    if len(ch) == 1:

    if ord(ch) < 32 or ord(ch) > 126:

    ch = ord(ch)

    elif ord(ch[0]) == 27:

    ch = '\033' + ch[1:]

    termios.tcsetattr(fdInput, termios.TCSADRAIN, termAttr)

    return ch

    内置的原始输入应该有帮助。

    1

    2

    3

    4for i in range(3):

    print ("So much work to do!")

    k = raw_input("Press any key to continue...")

    print ("Ok, back to work.")

    原始输入正在等待输入键

    我的python3解决方案,不依赖于任何PIP包。

    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# precondition: import tty, sys

    def query_yes_no(question, default=True):

    """

    Ask the user a yes/no question.

    Returns immediately upon reading one-char answer.

    Accepts multiple language characters for yes/no.

    """

    if not sys.stdin.isatty():

    return default

    if default:

    prompt ="[Y/n]?"

    other_answers ="n"

    else:

    prompt ="[y/N]?"

    other_answers ="yjosiá"

    print(question,prompt,flush= True,end="")

    oldttysettings = tty.tcgetattr(sys.stdin.fileno())

    try:

    tty.setraw(sys.stdin.fileno())

    return not sys.stdin.read(1).lower() in other_answers

    except:

    return default

    finally:

    tty.tcsetattr(sys.stdin.fileno(), tty.TCSADRAIN , oldttysettings)

    sys.stdout.write("

    ")

    tty.tcdrain(sys.stdin.fileno())

    我相信这是一个最优雅的解决方案。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17import os

    if os.name == 'nt':

    import msvcrt

    def getch():

    return msvcrt.getch().decode()

    else:

    import sys, tty, termios

    fd = sys.stdin.fileno()

    old_settings = termios.tcgetattr(fd)

    def getch():

    try:

    tty.setraw(sys.stdin.fileno())

    ch = sys.stdin.read(1)

    finally:

    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

    return ch

    然后在代码中使用它:

    1

    2if getch() == chr(ESC_ASCII_VALUE):

    print("ESC!")

    展开全文
  • (思考题:要是删除这个字符,该如何处理?) #define _CRT_SECURE_NO_WARNINGS #include<... printf("输入字符串:"); gets(arr1); printf("输入删除的字符"); ch = getchar(); for (i = 0; arr1[...

    (思考题:要是删除这个字符,该如何处理?)

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    int main()
    {
        char arr1[100], arr2[100];
        char ch;
        int i, j = 0;
        printf("输入字符串:");
        gets(arr1);
        printf("输入删除的字符");
        ch = getchar();
        for (i = 0; arr1[i] != '\0'; i++)
            if (arr1[i] != ch)
            {
                arr2[j++] = arr1[i];
                arr2[j] = '\0';
            }
        puts(arr2);
        return 0;
    }

     

    删除方法

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    int main()
    {
        char arr1[100], arr2[100];
        char ch;
        int i, j = 0,k;
        k = 0;
        printf("输入字符串:");
        gets(arr1);
        printf("输入计算的字符");
        ch = getchar();
        for (i = 0; arr1[i] != '\0'; i++)
            if (arr1[i] == ch)
                k++;
        printf("字符%c出现的次数为:%d",ch,k);
        return 0;
    }

    展开全文
  • 从键盘输入,并计算输出5.使用getchar(),gets(),getche(),getch()注:在下一次读取之前清空缓存 前言 随着工作的深入,你会发现光学会一门两门语言是完全没法适应越来越繁重的工作的,总会有或多或少的需求是需要...

    一、C基础—输出函数


    前言

    随着工作的深入,你会发现光学会一门两门语言是完全没法适应越来越繁重的工作的,总会有或多或少的需求是需要用到其他语言来解决的,最近开始接触了C的代码,所以来记录下学习过程,以防忘记(网上有太多安装教程了,大家搜索下就可以找到)

    一、开发工具

    CLang , windows

    二、步骤

    1.引入依赖

    #include <stdio.h>
    #include <windows.h>  //为了方便使用window的方法
    

    2.基础用法

    int main(){
    	/** c有两种输出控制台方法,puts只可以输出字符串,无法输出其他类型数据,而printf没有限制 */
    	puts("我爱工作");    //puts默认是换行的
        printf("工作使我又白又胖 \n");  //\n是转义符,回车键
        /** 在c中我们可以不需要写多个puts以及+号连接,可以直接输入多个字符串 */
        puts("我的很大"
             "你忍一下"
             "   吴签");
        printf("我的很大"
             "你忍一下"
             "   吴签");
    	}
    
    	return 0;
    

    3.进阶用法

    /** 处理方法要写到调用方法之前 */
    //自定义光标位置
    void setCursorPosition(int x,int y){
        //定位光标位置
        COORD coord;
        coord.X = x;
        coord.Y = y;
        //设置控制台位置,固定写法
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
    }
    
    //设置文字颜色
    void setColor(int color){
    	//设置文字参数,固定写法
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
    }
    
    int main(){
    	//设置颜色
        setColor(1);
        //设置光标位置
        setCursorPosition(1,1);
        puts("♠");
    
        setColor(5);
        setCursorPosition(2,2);
        puts("♥");
    
        setColor(9);
        setCursorPosition(3,3);
        puts("♦");
    
        setColor(13);
        setCursorPosition(4,4);
        puts("♣");
    
        //防止闪退,如图一
        getchar();
        //该方法会出现提示信息,但是在我测试的时候并没有成功,如图二(暂时未解决)
        //但是我通过引入  #include <unistd.h>  并使用 pause(); 成功暂停,只是无法继续往下运行,会卡到暂停那块,如图三
    //    system("pause");
    //    pause();
    
    	return 0;
    }
    
    
    

    图一
    图一
    在这里插入图片描述
    图二
    在这里插入图片描述
    图三

    4.从键盘输入,并计算输出

    int main(){
    	int a = 0,b = 0,c = 0,d = 0;
        char str[3];
        /** 这里的输入并没有关系,一个就行,因为在控制台输入的时候,如果不满足等同赋值数量的数据的话,
          * 系统不会继续进行处理,只有当满足当前条件的时候才会继续进行处理,如图三 
          */
        scanf("%d",&a); //输入整数并赋值给变量a
        scanf("%d",&b); //输入整数并赋值给变量b
        printf("%d + %d = %d \n",a ,b ,a + b);
        scanf("%d %d",&c ,&d);  //输入整数c,d并赋值
        printf("%d * %d = %d \n",c ,d , c * d);
        printf("请输入字符串:");
        scanf("%s", str);
        printf("%s \n", str);
    
        if(strcmp(str,"end") == 0){
            printf("即将结束");
            sleep(3);
        }else{
        	printf("结束");
    	}
        
        //防止闪退
        getchar();
        return 0;
    }
    
    

    图三
    图三

    5.分别使用getch,getche,scanf,gets来接收并输出

    1、getch

    int main(){
    	char str1,str2;
        str1 = getch();
        printf("我输入的第一个字符是:%c",str1);
        str2 = getch();
        printf("我输入的第二个字符是:%c",str2);	
        printf("结束 \n");
        sleep(3);
        //防止闪退
    //    getchar();
        //该方法会出现提示信息
        system("pause");
        return 0;
    }
    

    从这可以看出getch是没有缓存的,输入以后立马输出,并不需要用回车来结束当前输出

    	str1 = getch();
    	str2 = getch();
        printf("我输入的第一个字符是:%c",str1);
        getchar();
        printf("我输入的第二个字符是:%c",str2);
    

    而当我们在第一个输出之后添加一个等待,那么会出现第一个字符并不会立马输出,而是在回车或者任意字符之后同暂停一起输出
    在这里插入图片描述

    2、getche

    int main(){
        char str1,str2;
        str1 = getche();
        str2 = getche();
        printf("我输入的第一个字符是:%c",str1);
        printf("我输入的第二个字符是:%c",str2);
    }
    

    在这里插入图片描述

    3、scanf

    int main(){
    	char str1[3],str2[3];
        scanf("%s", &str1);
        printf("我输入的第一个字符是:%s",str1);
        scanf("%s", &str2);
        printf("我输入的第二个字符是:%s",str2);
        printf("结束 \n");
    }
    

    在这里插入图片描述
    同样的,使用scanf以及gets接收也出现缓存数据

    4、gets

    int main(){
    	char str1[3],str2[3];
        gets(str1);
        printf("使用gets获取的字符串1%s \n",str1);
        gets(str2);
        printf("使用gets获取的字符串2%s \n",str2);
    }
    

    在这里插入图片描述

    6.缓存

    int main(){
    	char str;
        char str1[50],str2[50],str3[50];
    
        str = getchar();
        printf("单独的字符串%c \n",str);
        gets(str1);
        printf("使用gets获取的字符串1%s \n",str1);
        gets(str2);
        printf("使用gets获取的字符串2%s \n",str2);
        gets(str3);
        printf("使用gets获取的字符串3%s \n",str3);
    
        printf("结束");
    
        sleep(3);
    
        //防止闪退
        getchar();
        //该方法会出现提示信息
    //    system("pause");
    
        return 0;
    }
    

    错误输入输出
    可以看到,当我们在输入单独的字符时,按下回车,gets会认为你的回车是一个字符串从而输出,这个又涉及到了缓存,在scanf缓存中我会说明(现在还没研究,只是单纯的写上了一个假链接)
    正确输入输出

    注:在下一次读取之前清空缓存

    scanf("%*[^\n]"); 
    scanf("%*c"); //在下次读取前清空缓冲区
    
    可以在下次输出前写上这条代码,scanf是可以写正则的

    前面我无法使用conio.h库的原因找到了,因为这个库不是标准库,只是在window下才会有,所以我们在选择的时候需要注意,如下图,MinGW是有该库的,而Cygwin是没有该库的,所以大家要注意一下
    在这里插入图片描述

    展开全文
  • C++输出中文字符

    千次阅读 2021-05-19 16:02:09
    cout场景1: 在源文件定义 const char* str = "中文" 在 VC++ 编译器上,由于Windows环境用 GBK编码,所以字符串 "中文" 被保存为 GBK内码,编译器也把 str 指向一个包含有 GBK编码的只读内存空间.用 cout 输出 str ...
  • windows系统查看字符集命令

    千次阅读 2021-01-14 14:10:11
    windows系统查看字符集命令:chcp 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。...
  • CEdit过滤输入字符需要重写. 以下是我重写的一个自定编辑框,能够过滤掉非十六进制相关字符并且...2.非限制时:可以输入任意字符,且不限制输入长度 示例代码下载:http://download.csdn.net/detail/qq_23992597/9590042
  • 思路:定义字符,判断字符在ASCII码的大小。 #include<stdio.h> #include<Windows.h> #include<time.h> #include<stdlib.h> void main() { char c; int letters=0,space=0,n...
  • shell字符串处理
  • 1、如何去掉字符不需要的字符?...(2)过滤某windows下编辑文本的'\r':'hello world\r\n' (3)去掉文本的unicode组合符号(调音):u'ní hǎo, chī fàn'(或 èěéēàǎā) 解决方案; ......
  • 文字/连字符在哪里,我该如何输入?例如,某些英语单词有连字符,例如高层。当然,有时是否有连字符都没有关系,并且不影响其含义。但是,有时有必要。例如,单词在行尾的位置是不够的。您只能写一半。此时,使用...
  • 匹配包含换行符(回车)的任意字符串的正则表达式 正则表达式Java  ...匹配字符串的过程经常会用到能够匹配包含换行符(回车)的任意字符串的正则表达式,即:[\s\S]* Java代码 收藏代码  String regex
  • #include <stdio.h> #include <windows.h> #include <conio.h>... //输入一个字符串,统计英文字母、空格、数字和其它字符的个数 char input[inputLen]; gets(input);//输入内容 c...
  • C语言关于汉字的处理

    千次阅读 2021-05-19 07:57:14
    目前许多C语言参考书中都没涉及到这个问题,程序多为处理英文变量和英文字符串,涉及到汉字的情况也大都是在printf语句输出提示信息或结果,如:printf("请输入a,b的值:\n");printf("输出功率为%s千瓦。\n",...
  • c语言将字符的小写字母转换成大写字母描述给定一个字符串,将其中所有的小写字母转换成大写字母。输入输入一行,包含一个字符串(长度不超过100,可能包含空格)。输出输出转换后的字符串。样例输入helloworld123...
  • Linux如何在屏幕上显示ASCII/中文字符

    千次阅读 多人点赞 2019-05-18 05:28:03
    如何在屏幕上显示一个字符? 很简单,调用 printf , 执行 echo … 然而,我们知道 任何显示的操作,最终都是在显示器上描像素 来完成的。换句话说,任何图案,包括GUI,文字字符等,全部是 画出来的! 把图案画出来...
  • shell 匹配正则 字符串处理

    千次阅读 2020-08-14 17:23:23
    很实用,建议收藏 shell里一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。...匹配输入字符串的结束位置
  • kafka windows版进入到windows目录下执行1)、创建主题2)、查看创建的主题3)、启动生产者此时,可输入任意字符,等消费者启动后,就能收到了。4
  • 本篇文章会用一行代码,让文本出现的数字序号可以按照数字顺序进行排序。
  • python分类统计字符个数

    千次阅读 2022-03-27 17:21:56
    编写程序,用户输入一个字符串,以回车结束,利用字典统计其中字母和数字出现的次数(回车符代表结束)。输入格式是一个以回车结束的字符串。例如输入abc1ab,输出{'a': 2, 'b': 2, 'c': 1, '1': 1}。
  • 另一个问题是,如果我在键盘录入字符,那么我如何截取键盘信息到被输入控件之间的信息,并加以转换成对于的文字后再写入该控件。我使用的是java的jna.jar。里面有Kernel32,User32,W32API等等的接口,但是找不到...
  • 请问python如何实现按任意键继续效果。嗯,请问哪里有中文的手册下载吗?还有,小编试了,pause命令编译时不认啊,。python请按任意键继续 什么意思pause命令就是按任意键继续,你按需要添加就行了你表述不清楚,小编写...
  • 实现python版本的按任意键继续/退出

    千次阅读 2020-12-19 10:06:30
    某天在群内有同学问到,在python下我用input或者raw_input都得输入完后回车才能获取到输入的值,那如何实现任意键退出暂停等功能呢,我当时也没有多想,因为接触python时间也不算长,主要还是Linux下的。要实现该...
  • 获取任意字符的Unicode值

    千次阅读 2016-08-02 18:57:32
    在javaSDK的bin目录下,有一个叫native2ascii.exe的程序,这个程序...一:将你想得到Unicode的任意字符(包括箭头,音乐符等特殊符号)写入记事本里,将后缀更改为 .properties (假设在d盘文件名为hello.properties)
  • Python实现按任意键继续/退出的功能

    千次阅读 2020-11-30 03:17:27
    前言要实现该功能,需要的就是暂停...msvcrt的 getch()方法 能够帮助在 Windows 下实现,其作用是获取一个按键响应并返回对应的字符。它并不在命令行回显。有如下程序段:import msvcrtprint ord(msvcrt.getch()...
  • 1.选择TextBox(允许用户输入文本,并提供多行编辑和密码字符掩码功); 2.选择label(为控件提供运行时信息或说明性文字); 3.选择Button(当用户单击它时引发事件); 在软件右下方有个属性的编辑框,可以修改...
  • 统计字符大小写字母的个数(10分) 分别统计字符大写字母和小写字母的个数. 函数接口定义: void fun ( char *s, int *a, int *b ); 其中s.a.b都是用户传入的参数.函数统计指针s所指字符大写字母和小写字母...
  • 访问局域网内的共享打印机,输入网络凭证总是提示不正确(访问机与被访问机都是win10系统)。...用户名:任意字符\你的真实用户名 密码:****** (如:a\admin) 就可以正常访问局域网内共享主机了。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 156,628
精华内容 62,651
热门标签
关键字:

windows中可以输入任意字符