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 不读取空格的主要内容,如果未能解决你的问题,请参考以下文章