2017-06-13 76 views
0

我正在搜索连接两个字符串(由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 

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

output

你怎么看concatena ()放在目标数组中只有第一个字符串... 非常感谢您的每一个答案!

+2

如果你想要一个空间,添加它。如果你不添加它,C不会。这一切都在你的掌控之中。权力是责任。 –

+0

首先以高级语言编写函数,然后将其翻译为程序集。错误是你的代码在没有混淆的情况下会非常明显。 – EOF

+0

更好:'无效concatena(const char * stringa,const char * stringa2,char * dest);'和'printf(“%s \ n”,dest);'也许在结束大括号前加上'return 0;' 'main()' – pmg

回答

0

在C中,strcat相当于自动会预先考虑第二个字符串前的空间将是这个样子:

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

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

+0

我正在寻找一个装配解决方案,所以这就是为什么我把标签“masm”,但我不知道你为什么删除它... 谢谢你的答案! –

+0

@AlessandroBarrili因为您的问题是关于“x86”汇编,而不是专门关于MASM汇编程序。 –

+0

我使用masm语法编写它... –

0

更proft将下面的代码:

#include <string.h> 

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

享受

,如果你想传递结果thisrd字符串,只是:

#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; 
} 
+0

这是非常低效的。例如,它需要遍历第一个字符串三次(一次将它复制到dest,一次添加一个空格,一次在空格之后)。注释掉的替代选项不起作用;当dest以这种方式创建时,dest不一定会被清零(如果是这样,效率会更低)。我不知道为什么OP需要一个汇编解决方案,但我怀疑C方案效率低下。 –

+0

丹尼尔怎么说:我正在寻找一个装配解决方案......在C我知道该怎么做! 谢谢你的回答:) –

0

有许多方面,这可能是完成但一般来说,我喜欢尽可能简化。在这种情况下,程序框架并不是真正必要的,但是因为您已将它包含在您的示例中,我也这样做了。

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 
+0

你会怎么做?我正在学习使用它,所以如果你能教我一个更好的程序...我在这里:)非常感谢你! –

+0

@AlessandroBarrili Better是一个相对术语,因为每个人都会有更好的自己的想法。最后,算法是否给你你想要的结果。用这个例子代替你的代码,然后用调试器追踪它,你会得到一个真正清晰的想法。学习只是了解指令集,然后尝试使用代码,然后尝试调整它以改善空间和/或速度。 –

-1

我找到了解决的办法! 有人回答/在这里说,把'dest''esi'(索引)中的第一个字符串指向“行尾”或类似的东西...因此,解决方案非常非常简单,我减少它,然后增加它..! 它更简单的把它写的是解释,我只改变塔标签“空间”这样的:

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

所以,谢谢大家!

+0

太棒了!你把“downvote”作为我的回答,但NOBODY给我一个解决方案!也许它是一个粗鲁的解决方案,但在asm和工作! –