编程马拉松(4)
引自第八阁论坛:http://bbs.chinadbg.cn/forum-7-1.html飞翔技术论坛:http://www.powk.net/bbs/forumdisplay.php?fid=4&page=1
目的,主要是熟悉字串操作。
键盘输入两组字串,要求大于6个小于20并比较两组串是不是相等,如小于6大于20或相等重新输入,然后
输入出较大的串
字符串比较原理:是把每个字符串的第一个字符的ASCII码比较如果A串第一个字符大于B串第一个字符,A
串大于B串,如果相等比第二个字符,大小同第一个字符的比较,如果完全相同就是相等。
天圆地方所写delphi代码
procedure TForm1.Button1Click(Sender: TObject);
var
TmpString:array of String;
i,Error:Integer;
begin
Error:=1;
i:=0;
while Error<>0 do
begin
TmpString:=InputBox('请输入字符串'+IntToStr(i+1),'要求字符串字数大于6小于
20','123343434126s');
If (length(TmpString)<7) or (Length(TmpString)>19) then
begin
showmessage('字符串'+IntToStr(i)+'字数不对!'+'请重新输入..');
Continue;
end;
Inc(i);
if i=2 then
begin
i:=0;
if TmpString=TmpString then ShowMessage('字符串相同请重新输入')
else if Length(TmpString)>length(TmpString) then
begin
ShowMessage('较大的为字符串1:'+TmpString);
Error:=0;
end
else
begin
ShowMessage('较大的为字符串2:'+TmpString);
Error:=0;
end;
end;
end;
end;
freesoft 写的C代码:此代码有一点小错啊。希望能找出来
以下是C代码,程序有点有错,好好看看。
#include "stdio.h"
#include "conio.h"
#include "string.h"
main()
{
int len1=0,len2=0,max=0;
char st1,st2; /*定义两个字串*/
while(max==0)
{
while (len1==0)
{
printf("input string(1):\n");
gets(st1); /*输入字串1也可以用scanf("%s",st1)*/
printf("You input string(1):\n") ;
puts(st1);
len1=strlen(st1) ;
if (len1<=6)
{
printf("%d\n",len1);
len1=0 ;
printf("You string(1) access err (<=6 )");
}
if (len1=>20)
{
printf("%d\n",len1);
len1=0 ;
printf("You string(1) access err (=>20)");
}
}
while (len2==0)
{
printf("input string(2):\n");
gets(st2); /*也可以用scanf("%s",st2)*/
printf("You input string(2):\n") ;
puts(st2);
len2=strlen(st2) ;
if (len2<=6)
{
len2=0 ;
printf("You string(2) access err (<6 =)");
}
if (len2=>20)
{
len2=0 ;
printf("You string(2) access err ( =>20)");
}
}
max=strcmp(st1,st2);
if(max=0)
{
len1=len2=max=0;
printf("Access err,string(1)=string(2)") ;
}
if(max>0)
{
max=1;
printf("string(1)>string(2)>>string(1)=%S\n",st1);
}
else
{
max=-1;
printf("string(2)>string(1)>>string(2)=%s\n",st2);
}
getch();
}
}
meiyululu 的汇编代码
;第一个文件 Strings.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming >
; by
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Strings.asm
; 字符串处理
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Strings.asm
; rc Strings.rc
; Link /subsystem:windows Strings.obj Strings.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include string.inc
includelib string.LIB
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDD_DIA equ 106
IDC_STR1 equ 1000
IDC_STR2 equ 1001
IDC_MAX equ 1002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
.data
str1 db 255 dup(0)
str2 db 255 dup(0)
s db 0, 0
.const
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 字符串处理函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MyStrProc procuses ebx edi esihWnd
invoke SetDlgItemText, hWnd, IDC_MAX, addr s
invoke RtlZeroMemory, addr str1, sizeof str1
invoke RtlZeroMemory, addr str2, sizeof str2
invoke GetDlgItemText, hWnd, IDC_STR1, addr str1, sizeof str1
invoke GetDlgItemText, hWnd, IDC_STR2, addr str2, sizeof str2
invoke _strlen, addr str1
.if eax > 20 || eax <=6
invoke SetDlgItemText, hWnd, IDC_STR1, addr s
ret
.endif
invoke _strlen, addr str2
.if eax >= 20 || eax <=6
invoke SetDlgItemText, hWnd, IDC_STR2, addr s
ret
.endif
invoke_strcmp, addr str1, addr str2
;********注意以下不能用.if .elseif .endif伪指令 ,因为eax 的值
可能是负数
;********而这几个 伪指令 都是无符号数的比较
;
;在分支和循环的伪指令反汇编后可以发现,在使用>、>=、<和<=比较符时,
;MASM的伪指令总是将比较以后的跳转指令使用为jb和jnb等无符号数比较跳
转的指令,
; 这就意味着,MASM的条件测试总是把操作数当做无符号数看待,这样,假
设eax等于1,
;那么表达式(eax > -1)的值是“假”,因为-1表示为0ffffffffh,如果当
做无符号数看,
;它是最大的数!如果程序中需要构造有符号数的比较分支或循环结构,
; 那么必须另外用jl和jg等有符号数比较跳转的指令来完成,
;使用条件测试配合分支或循环伪指令可能会得到错误的结果!
cmpeax , 0
jl L_L
jg L_G
invoke SetDlgItemText, hWnd, IDC_MAX, addr str1
jmp L_END
L_L: invoke SetDlgItemText, hWnd, IDC_MAX, addr str2
jmp L_END
L_G: invoke SetDlgItemText, hWnd, IDC_MAX, addr str1
L_END:
ret
_MyStrProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 对话框处理函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_MyDialogProc proc hWnd,uMsg,wParam,lParam
mov eax, uMsg
.ifeax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_COMMAND
mov eax, wParam
movzx eax, ax
.if eax == IDOK
invoke _MyStrProc, hWnd
.elseif eax == IDCANCEL
invoke EndDialog, hWnd, NULL
.endif
.else
mov eax, 0
ret
.endif
mov eax, 1
ret
_MyDialogProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_DIA,NULL,offset _MyDialogProc,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;第二个文件 String.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;Written by
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; string.asm
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
.code
;********************************************************************
; void *_Cdecl memchr (const void *s, int c, size_t n);
;********************************************************************
_memchr proc uses ediecx sstr, char, szn
mov edi, sstr
mov al, byte ptr
mov ecx, szn
cld
repnz scasb
mov eax, edi
dec eax
mov cl, byte ptr
cmp cl, byte ptr
jnz NOTFIND
ret
NOTFIND:mov eax, 0
ret
_memchr endp
;********************************************************************
;int _Cdecl string (const void *s1, const void *s2, size_t n);
;********************************************************************
_memcmp proc uses edi esi ecx dstr, sstr, szn
mov esi, sstr
mov edi, dstr
mov ecx, szn
cld
repe cmpsb
dec esi
dec edi
movzx eax, byte ptr
sub al, byte ptr
movsx eax, al
ret
_memcmp endp
;********************************************************************
; void *_Cdecl memcpy (void *dest, const void *src, size_t n);
;********************************************************************
_memcpy procuses edi esi ecx dstr, sstr, szn
mov esi, sstr
mov edi, dstr
mov ecx, szn
cld
repmovsb
mov eax, dstr
ret
_memcpy endp
;********************************************************************
; void *_Cdecl memset (void *s, int c, size_t n);
;********************************************************************
_memsetprocuses edi esi ecx dstr, char, szn
mov ecx, szn
mov edi, dstr
mov al, byte ptr
rep stosb
mov eax, dstr
ret
_memsetendp
;********************************************************************
;size_t _Cdecl strlen (const char *s);
;********************************************************************
_strlen proc uses edisstr
mov edi, sstr
mov al, 0
LS: cmp al, byte ptr
jz RETURN
inc edi
jmp LS
RETURN: mov eax, edi
sub eax, sstr
ret
_strlen endp
;********************************************************************
; int _Cdecl strcmp (const char *s1, const char *s2);
;********************************************************************
_strcmp proc uses edi esi ecx ebx dest, src
local @n:DWORD
invoke _strlen, dest
mov ecx, eax
invoke _strlen, src
mov ebx, eax
cmp ecx, ebx
jle ABOVE
mov @n, eax
jmp MEMCMP
ABOVE: mov @n, ecx
MEMCMP: invoke _memcmp, dest, src, @n
cmp eax,0
jz CMPNEXT
ret
CMPNEXT: mov eax, ecx
sub eax, ebx
ret
_strcmp endp
;********************************************************************
; char *_Cdecl strcpy (char *dest, const char *src);
;********************************************************************
_strcpy proc uses edi esi ecx dest, src
invoke _strlen, src
mov ecx, eax
inc ecx
invoke _memcpy, dest, src, ecx
mov eax, dest
ret
_strcpy endp
;********************************************************************
; char *_Cdecl strcat (char *dest, const char *src);
;********************************************************************
_strcat proc uses edi esi ecx dest, src
mov edi, dest
invoke _strlen, dest
add edi, eax
invoke _strcpy, edi, src
mov eax, dest
ret
_strcat endp
;********************************************************************
; char *_Cdecl strlwr (char *s);
;********************************************************************
_strlwr proc uses edi esi ecx sstr
mov edi, sstr
mov al, 0
LS: mov ah, byte ptr
cmp al, ah
jz RETURN
cmp ah, 'A'
jb NEXT
cmp ah, 'Z'
ja NEXT
add ah, 32
mov byte ptr , ah
NEXT: inc edi
jmp LS
RETURN:
mov eax, sstr
ret
_strlwr endp
;********************************************************************
; char *_Cdecl strupr (char *s);
;********************************************************************
_strupr proc uses edi sstr
mov edi, sstr
mov al, 0
LS: mov ah, byte ptr
cmp al, ah
jz RETURN
cmp ah, 'a'
jb NEXT
cmp ah, 'z'
ja NEXT
sub ah, 32
mov byte ptr , ah
NEXT: inc edi
jmp LS
RETURN:
mov eax, sstr
ret
_strupr endp
end
kill203的C++代码
//by kill203
//关于C++字符串的相关操作的练习。。。
#include<iostream>
#include<string>
using namespace std;
int strcm(char* str1,char* str2);
void main()
{
char str1,str2;
char str3[]="您输入的字符串长度小于6,请重新输入!";
char str4[]="您输入的字符串长度大于20,请重新输入!";
L1:cout<<"您第一个字符串是:";
cin>>str1;
if(strlen(str1)<6)
{ cout<<str3<<endl;
goto L1;
}
else if(strlen(str1)>20)
{ cout<<str4<<endl;
goto L1;
}
L2: cout<<"您第二个字符串是:";
cin>>str2;
if(strlen(str2)<6)
{ cout<<str3<<endl;
goto L2;
}
else if(strlen(str2)>20)
{ cout<<str4<<endl;
goto L2;
}
if (strcm(str1,str2)==1)
cout<<"你输入的这两个字符串不相等!"<<endl;
else
cout<<"你输入的这两个字符串相等!"<<endl;
}
int strcm(char* str1,char* str2)
{
int i,c,d,re;
if (strlen(str1)<=strlen(str2))
{
for(i=1;i<strlen(str1);i++)
{ c=str1;d=str2;
if (c!=d)
re=1;goto LS;
}
}
else
{ for(i=1;i<=strlen(str2);i++)
{ c=str1;d=str2;
if (c!=d)
re=1;goto LS;
}
}
LS: return re;
}
经过修改后的代码,只是函数优化了
//by kill203
//关于C++字符串的相关操作的练习。。。
#include<iostream>
#include<string>
using namespace std;
int strcm(char* str1,char* str2);
void main()
{
char str1,str2;
char str3[]="您输入的字符串长度小于6,请重新输入!";
char str4[]="您输入的字符串长度大于20,请重新输入!";
L1:cout<<"您第一个字符串是:";
cin>>str1;
if(strlen(str1)<6)
{ cout<<str3<<endl;
goto L1;
}
else if(strlen(str1)>20)
{ cout<<str4<<endl;
goto L1;
}
L2: cout<<"您第二个字符串是:";
cin>>str2;
if(strlen(str2)<6)
{ cout<<str3<<endl;
goto L2;
}
else if(strlen(str2)>20)
{ cout<<str4<<endl;
goto L2;
}
if (strcm(str1,str2)==1)
cout<<"你输入的这两个字符串不相等!"<<endl;
else
cout<<"你输入的这两个字符串相等!"<<endl;
}
int strcm(char* str1,char* str2)
{
while((*str1==*str2)&&(*str1))
{
str1++;
str2++;
}
if((*str1==*str2)&&(!*str1)) //如果str1=str2,且没有超出str1数组的边界
return 0;
else if((*str1)&&(!*str2)) //如果str1比str2的长度长
return 1;
else if((*str2)&&(!*str1)) //如果str2比str1的长度长
return 1;
else
return((*str1>*str2)?1:1);
/*
条件运算符:
?:
它是C语言中唯一的一个三目运算符,用来对条件求值,具有右结合性。
条件表达式:用条件运算符连接起来的式子。
其形式如下:
表达式1?表达式2:表达式3
运算规则:先计算表达式1,如果结果为真,则计算表达式2,并把表达式2的值作为整个表达式的值。
否则,如果表达式1的值为假,则计算表达式3,并把表达式3的值作为整个表达式的值。
例如:要得到变量a与b之间的最小值,可以表示成:
min = (a < b) ? a : b; //如果a < b,则min=a,否则a>=b,则min=b
*/
}
------------------------------------------------------
21st呵呵,偶来了
看了看楼主给的一个朋友写得c++,稍微有些粗糙。不到万不得已的时候,尽量不要用goto.
language: c++
#include <iostream>
#include<cstring>
using namespace std;
int main()
{
string s1,s2;
int len1,len2;
while(1)
{
cin>>s1>>s2;
len1=s1.length();
len2=s2.length();
if(len1>6&&len1<20&&len2>6&&len2<20)
{
int i=0;
int min=len1<len2?len1:len2;
bool quitflag=false;
while(i<=min)
{
if(s1>s2)
{
cout<<s1<<"\n";
quitflag=true;
break;
}
else if(s1<s2)
{
cout<<s2<<"\n";
quitflag=true;
break;
}
else
{
i++;
}
}
if(quitflag==true)
{
break;
}
else
{
cout<<"they are equal,please retry!\n";
}
}
else
{
cout<<"out of range,please retry!\n";
}
}
return 0;
}
页:
[1]