我如何逐字符遍历一个字符串 [英] How can I traverse a string character by character
问题描述
我有一个C程序,该程序从标准输入中接收字符串,并将其传递给用32位x86汇编语言编写的函数,该函数必须执行以下操作:
I have a C program that receives a string from the standard input and passes it to an function written in 32-bit x86 assembly which which has to do following things:
- 检查字符串是否仅由字母数字字符组成.
- 如果先前测试的答案是肯定的,则按原样返回字符串
- 如果有一些非字母数字字符,该函数必须使用空格删除它们.
- 检查完字符串中的每个字符后,该函数必须返回不包含非字母数字字符的字符串.
以下是该例程必须执行的操作的一个示例:
Here an example of what that routine has to do:
"only 4lph4numeric chars" INPUT
"only 4lph4numeric chars" OUTPUT
"here*some*for$bidden_chars#" INPUT
"here some for bidden chars" OUTPUT
我是汇编语言的新手,但我知道如何比较字符,我认为删除其中一个就足以用空格代替它.
I'm new to assembly but I know how to compare character, I think that to remove one of them is enough to substitute it with a blank space.
真正的问题是我不知道如何逐个字符地遍历字符串.我已经阅读了有关lods
的内容,但我不知道如何使用它.
The real problem is that I don't know how to traverse the string character by character; I've read something about lods
but I've not understood how to use it.
推荐答案
这就是您的操作方式.下一个代码是使用Visual Studio 2010 C ++控制台项目制作的.首先,在汇编部分,请注意注释,如何从堆栈中获取字符串的地址,如何访问字符以及最重要的部分,如何删除不需要的字符:
This is how you do it. Next code was made with Visual Studio 2010 C++ console project. First, the assembly part, pay attention to the comments, how to get the string's address from stack, how the characters are visited, and the most important part, how the undesired chars are deleted:
.386
.model flat, C
.code
;-------------------------------------------------------
check_alphanum proc
;PRESERVE EBP, ESI.
push ebp
push esi
mov ebp, esp
add ebp, 12 ;GET PARAMETER'S ADDRESS.
mov esi, [ ebp ] ;ESI POINTS TO ARRAY.
whil:
mov al, [ esi ] ;GET CURRENT CHAR.
cmp al, 0 ;CHECK END OF ARRAY.
je finale ;IF ( AL == 0 ) END OF STRING.
;CHECK IF CURRENT CHAR IS 0..9-A..Z-a..z.
cmp al, '0'
jb its_invalid ;IF ( AL < '0' ) INVALID.
cmp al, '9'
jbe its_valid ;IF ( AL <= '9' ) VALID.
cmp al, 'A'
jb its_invalid ;IF ( AL < 'A' ) INVALID.
cmp al, 'Z'
jbe its_valid ;IF ( AL <= 'Z' ) VALID.
cmp al, 'a'
jb its_invalid ;IF ( AL < 'a' ) INVALID.
cmp al, 'z'
jbe its_valid ;IF ( AL <= 'z' ) VALID.
jmp its_invalid ;INVALID BECAUSE AL > 'z'.
its_valid:
;NEXT CHAR TO PROCESS.
inc esi
jmp whil
its_invalid:
;DELETE CURRENT CHAR PUSHING ALL CHARS ONE PLACE TO THE LEFT.
mov edi, esi ;EDI POINTS TO CURRENT CHAR TO DELETE.
mov ebx, esi ;EBX ALSO POINTS TO CURRENT CHAR.
inc ebx ;NOW EBX POINTS TO NEXT CHAR.
shifting_left:
mov al, [ ebx ] ;AL = NEXT CHAR.
mov [ edi ], al ;CURRENT CHAR REPLACED BY NEXT.
cmp al, 0
je end_shifting
inc edi
inc ebx
jmp shifting_left
end_shifting:
jmp whil ;REPEAT PROCESS FOR NEXT CHAR.
finale:
;RESTORE EBP, ESI.
pop esi
pop ebp
ret
check_alphanum endp
;-------------------------------------------------------
end
现在是C ++部分.例如,可以从"main"方法中这样调用上一个过程:
Now the C++ part. Previous procedure can be called like this, for example, from the "main" method:
extern "C" void check_alphanum ( char * arr );
...
char arr[] = "A213457B-3746DFA3-578EC20E-4567DFF2-08A1B3AC-7B125F3A";
check_alphanum( arr );
结果字符串为:
"A213457B3746DFA3578EC20E4567DFF208A1B3AC7B125F3A"
下一张图片显示了外部程序集文件在项目树中的什么位置:
Next image shows where is the external assembly file in the project tree:
您要做的就是将新文件添加到您的项目中,根据需要命名,但是使用".asm"扩展名,将我的代码复制粘贴到该文件中,就可以使用了(或准备好致电).
All you have to do is add a new file to your project, name it as you want but use the ".asm" extension, copy-paste my code in it, and that's it, ready to use (or ready to call).
这篇关于我如何逐字符遍历一个字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!