【问题标题】:put space between concatenate strings在连接字符串之间放置空格
【发布时间】:2017-06-13 16:18:40
【问题描述】:

我正在搜索连接两个字符串(由 C 传递),将结果放在第三个字符串中。我做到了,但我知道我想在字符串之间放置一个空格,但是......不可能......! 这是C的部分

#include <stdio.h>
#include <string.h>

void concatena(char *stringa, char *stringa2, char *dest);

int main(void)
{
    char stringa[17] = { "stringa numero 1" };
    char stringa2[17] = { "stringa numero 2" };
    char dest[34] = { "" };

    concatena(stringa, stringa2, dest);

    printf("%s", dest);

    getchar();
}

调用masm32的部分:

.586
.model flat
.code

_concatena proc

;pre
push ebp
mov ebp,esp
push ebx
push edi
push esi

;clean
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
xor esi, esi
xor edi, edi


mov eax, dword ptr[ebp+8]           ;source=stringa
mov ebx, dword ptr[ebp+12]          ;target=stringa2
mov ecx, dword ptr[ebp+16]          ;buffer=dest

inizio:
mov dl,byte ptr[eax+esi*1]
cmp dl,0
je space ;first string finished
mov byte ptr[ecx+esi*1], dl
inc esi
jmp inizio

space:
inc esi
mov byte ptr[ecx+esi*1],32
;if i put a 'inc esi' here the result is the same
jmp fine1

fine1:

mov dl, byte ptr[ebx+edi*1]
cmp dl, 0
je fine2 ;second string finished
mov byte ptr[ecx+esi*1], dl
inc edi
inc esi
jmp fine1

fine2:

;post
pop esi
pop edi
pop ebx
pop ebp

ret

;chiusura della procedura
_concatena endp
end

当我在输出中运行它时,我看到:

您如何看到 concatena() 仅将第一个字符串放入目标数组... 非常感谢您的每一个回答!

【问题讨论】:

  • 如果你想要一个空间,添加它。如果你不添加它,C 就不会。这一切都在你的控制之下。权力带来责任。
  • 从用高级语言编写函数开始,然后将它翻译成汇编。错误是你的代码在没有混淆的情况下会很明显。
  • 更好:void concatena(const char *stringa, const char *stringa2, char *dest);printf("%s\n", dest); 并且可能在 main() 的右大括号之前添加 return 0;
  • char stringa[17] = { "stringa numero 1" }; 是无效的初始化程序。取下大括号。

标签: assembly x86 masm string-concatenation


【解决方案1】:

在 C 中,strcat 等效项会在第二个字符串之前自动添加一个空格,如下所示:

void strcatspace(char *dest, char *src)
{
    char *insert_point = &dest[strlen(dest)];
    *insert_point++ = ' ';
    while(*src) *insert_point++ = *src++;
}

尚未测试,但这是一般的想法。将此函数转换为汇编以实现预期结果,可能使用编译器生成的指令作为起点。

【讨论】:

  • 我正在寻找一个组装解决方案,所以我把标签“masm”,但我不知道你为什么删除它...谢谢你的回答!
  • @AlessandroBarrili 因为您的问题是关于“x86”程序集,而不是关于 MASM 汇编程序。
  • @AlessandroBarrili 你是用 Intel 语法写的,这不是 MASM 特有的。
【解决方案2】:

更多的利润将是以下代码:

#include <string.h>

void strcat_space(char* dest, char* src){
    strcat(dest, " ");
    strcat(dest, src);
}

享受

如果你想将结果传递给这个字符串,只需:

#include <string.h>

int main(){
   char str1[] = "abcd";
   char str2[] = "efgh";
   char dest[1000];

   strcat_space(strcpy(dest, str1), str2);
   /*
    // or you can also do
        strcat(dest, str1);
        strcat_space(dest, str2);    
   */

   return 0;
}

【讨论】:

  • 这是非常低效的。例如,它需要遍历第一个字符串 3 次(一次复制到 dest,一次添加空格,一次在空格之后)。注释掉的替代选项不起作用; dest 在以这种方式创建时不一定会归零(如果是这样,那效率会更低)。我不知道为什么 OP 想要一个汇编解决方案,但我怀疑效率低下的 C 解决方案是否有效。
  • 丹尼尔怎么说:我正在寻找一个装配解决方案...在 C 语言中我知道该怎么做!谢谢你的回答:)
【解决方案3】:

有很多方法可以做到这一点,但总的来说,我喜欢尽可能地简化。在这种情况下,过程框架并不是真正需要的,但是因为您已将其包含在示例中,所以我也这样做了。

    push    ebp
    mov     ebp, esp

    push    esi
    push    edi

; So second iteration of MoveStr will drop into Done    
    push    Done

    mov     edi, dword ptr [ebp+16]   ; Grab pointer to destination buffer

    mov     esi, dword ptr [ebp+8]    ; Pointer to string 1
    call    MoveStr
    or      al, ' '
    stosb
    mov     esi, dword ptr [ebp+12]

MoveStr:
    lodsb
    or      al, al
    jnz     L1
    ret
L1: stosb
    jmp     MoveStr

Done:
    pop     edi
    pop     esi
    leave
    ret

【讨论】:

  • 你会怎么做?我正在学习使用它,所以如果你能教我一个更好的程序......我在这里:) 非常感谢!
  • @AlessandroBarrili 更好是一个相对的术语,因为每个人都会对更好的东西有自己的想法。最后,算法是否会给你想要的结果。用此示例替换您的代码,然后使用调试器对其进行跟踪,您将真正清楚地了解它是如何工作的。学习只是简单地了解指令集,然后对首先有效的代码进行试验,然后尝试对其进行调整以提高空间和/或速度。
【解决方案4】:

我找到了解决方法! 有人在这里回答/评论说,在将第一个字符串放入“dest”后,“esi”(索引)指向“行尾”或类似的东西...... 所以解决方案非常简单,我减少它,然后增加它..! 写起来更简单,解释一下,我只改变了这样的标签“空格”:

space:
dec esi ;decrease
inc esi ;increase
mov byte ptr[ecx+esi*1],20h 
inc esi
jmp fine1

所以谢谢大家!!

【讨论】:

  • 太棒了!您对我的回答投了“反对票”,但没有人给我一个解决方案!也许这是一个粗鲁的解决方案,但在 asm 和工作中!!
猜你喜欢
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多