freesoft 发表于 2007-8-14 07:46:33

编程马拉松(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]
查看完整版本: 编程马拉松(4)