MASM x86-64 scanf 不读取空格

Posted

技术标签:

【中文标题】MASM x86-64 scanf 不读取空格【英文标题】:MASM x86-64 scanf not reading spaces 【发布时间】:2017-10-21 21:22:29 【问题描述】:

我有一个简单的 64 位汇编程序,我们正在上课。它应该接受用户输入(字符串)并将带有小写字母的字符串返回为大写字母,将大写字母返回为小写字母。

根据我所拥有的,它会读取任何内容,直到找到一个空格,之后就不会再读取了。因此,如果我输入“test”,它将输出“TEST”。如果我输入“test Test”,它将输出“TEST”。但是,如果我在第一个单词之前添加空格,它将输出第一个单词但会删除空格。例如:输入“TestT”,输出:“tESt”。 任何人都知道我该如何解决这个问题? 这是我的整个程序:

;Author: Keenan Kaufman
;Date: 10/20/2017
INCLUDELIB msvcrt.lib

printf PROTO
scanf  PROTO
exit   PROTO

.DATA
CRLF BYTE 0Dh, 0Ah, 0                           ;carriage return
msgHeader   BYTE    "Enter a mixed case string: ", 0
message     BYTE    20 DUP(0), 0
target      BYTE    SIZEOF message DUP(?), 0Dh, 0Ah, 0
msgformat   BYTE    "%20s", 0

.CODE
main    PROC
;Display request for user input
        lea rcx, msgHeader
        call printf

;obtain user input
        lea rcx, msgformat
        lea rdx, message
        call scanf


        lea rsi, message
        lea rdi, target

        jmp GETNEXT
GETNEXT:
        mov al, [rsi]
        cmp al, 0
        je  ENDCASE
        cmp al, 'z'
        ja  NOCHANGE
        cmp al, 'A'
        jb  NOCHANGE
        cmp al, 'a'
        jae TOUPPER
        cmp al, 'Z'
        jbe TOLOWER

TOUPPER:
        sub al, 32
        mov [rdi], al
        inc rdi
        inc rsi
        jmp GETNEXT
TOLOWER:
        add al, 32
        mov [rdi], al
        inc rdi
        inc rsi
        jmp GETNEXT
NOCHANGE:
        mov [rdi], al
        inc rdi
        inc rsi
        jmp GETNEXT
ENDCASE:
        jmp FINISH
FINISH:
        ;Display target
        lea rcx, target
        call printf
        lea rcx, CRLF
        call printf


        mov rax, 0
        call exit
main ENDP
END

【问题讨论】:

【参考方案1】:

是的,这是scanf 的一个功能。这是 scanf 的 Linux 手册页,对于 %s 格式,它说:

s 匹配一系列非空白字符;下一个 指针必须是指向字符初始元素的指针 足够长的数组来保存输入序列和 终止空字节 ('\0'),它是自动添加的。这 输入字符串在空白处或最大字段宽度处停止, 以先到者为准。

要做你想做的事,直接从stdin使用read()getc()fgets()读取字符。

【讨论】:

scanf 格式没有“精度”——只有 printf 格式。没有办法在s 转换中指定最小字符数,也没有办法让它读取空格。更好的方法是%20[^\n] @ChrisDodd 我希望我的程序能够读取空白,所以我猜现在我不应该有 s。无论如何我可以使用 scanf 并读取空格吗? @ChrisDodd 当我使用 %20[^\n] 并在我键入字符串后按回车键时,它什么也不做,就像它仍在尝试读取更多输入一样。 Scanf 用于读取 formatted 输入,例如以空格分隔的字段。由于您想读取未格式化的输入,请使用 fgets 或 getchar。 @KeenanKaufman:请注意,\n 必须是汇编器输出中字符串内的文字换行符,而不是反斜杠和 n。您的汇编程序可能不会像 C 编译器那样处理 C 转义序列。 (在 NASM 中,您必须使用反引号而不是双引号来获得 C 风格的 \ 处理。关于 MASM 的 IDK。)无论如何,您可以 db "%20 [^", 0Ah, "]", 0 使用其数字代码组装 ASCII 换行字节。 (MASM 不接受十六进制的 0xa

以上是关于MASM x86-64 scanf 不读取空格的主要内容,如果未能解决你的问题,请参考以下文章

64位的汇编怎么搞

ASM:MASM、NASM、FASM?

C语言tips_2 关于scanf 读取规则小结

如何使用scanf读取以空格分隔的数字

scanf和gets的差别

为啥不能用scanf读入一个含有空格的字符串