请告诉我为什么我的文本没有对齐?

huangapple go评论65阅读模式
英文:

Please advise why my text is not aligned?

问题

这是关于链式对齐的问题。

编写函数void align_str(char *output, char *in, unsigned int size, int align),该函数根据以下规则将输入字符串等效于输出字符串,并将结果传递到指定的内存位置。由输出参数指定。

  • 链的输出长度与大小相同。
  • 参数alignment指定对齐方式如下:0 = 左对齐,1 = 居中,2 = 右对齐,其他值结果未定义。
  • 在左对齐的情况下,第一个字符永远不是空格。
  • 在右对齐的情况下,最后一个字符永远不是空格。
  • 链被填充以达到所需长度。
  • 在居中对齐的情况下,空格等量填充在链的开头和结尾。
  • 假设输入仅包含ASCII表中范围为0x20到0x7e(包括在内)的字符。
  • 如果无法满足所有条件(例如,文本的长度不包括开头和结尾的空格大于大小),则结果未定义。

你提供的代码似乎是x86汇编语言的实现,用于处理字符串对齐。如果你需要进一步的信息或帮助,请告诉我。

英文:

This question is about chain alignment.
Program the function void align_str(char \*output, char \*in, unsigned int size, int align) which equals the input string according to the following rules and the result of the delivery for the memory location specified.
Valued by the output argument.

  • The output length of chain is the same size.
  • Argument alignment specifies the alignment as follows: 0 = left, 1 = center, 2 = right, for other
    value, the result is undefined.
  • In case of left alignment, the first character is never a space.
  • In the case of right alignment, the last character is never a space.
  • The chain is completed with gaps to the required length.
  • In the case of center alignment, spaces are filled equally at the beginning and end of the chain.
  • Assume that the input contains only ASCII table characters from the range 0x20 to 0x7e (inclusive).
  • If all conditions cannot be met (e.g. the length of the text without opening and closing spaces is longer
    than size), the result is undefined.
 align_str:
    push rbp
    mov rbp, rsp
    push rbx
    push r12
    push r13

    ; Save registers on the stack

    mov r12, rdi ; r12 = output string
    mov r13, rsi ; r13 = input string
    mov ebx, edx ; ebx = output string size
    mov edi, ecx ; edi = alignment

    ; Calculate the length of the input string

    xor ecx, ecx ; ecx = 0
    xor edx, edx ; edx = 0

    strlen_loop:
        mov al, byte [r13 + rcx]
        cmp al, 0
        je end_strlen
        inc edx
        inc ecx
        jmp strlen_loop

    end_strlen:

    ; Calculate the number of spaces needed for alignment

    mov eax, ebx ; eax = size
    sub eax, edx ; eax = size - input string length
    jle align_done ; if less than or equal to 0, skip alignment

    cmp ebx, 0 ; check if output string size is greater than 0
    jle align_done ; if not, skip alignment

    pad_spaces:
        mov ebx, eax ; ebx = number of spaces to pad
        cmp edi, 0 ; check alignment
        je align_left
        cmp edi, 1
        je align_center
        cmp edi, 2
        je align_right
        ; Invalid alignment value
        jmp align_done

    align_left:
        jmp pad_left
    align_center:
        shr ebx, 1 ; divide by 2
        jmp pad_center
    align_right:
        jmp pad_right

    pad_right:
        mov rdx, r12 ; rdx = output string
        add rdx, rax ; rdx = output string + number of spaces to pad on the right
        mov byte [rdx], 0 ; null-terminate
        mov rdx, r12 ; rdx = output string
        mov rcx, r13 ; rcx = input string
        xor eax, eax ; eax = 0
        pad_right_loop:
            mov al, byte [rcx]
            mov byte [rdx], al
            inc rdx
            inc rcx
            cmp byte [rcx - 1], 0 ; check if we reached the end of the input string
            jne pad_right_loop
        xor ecx, ecx ; ecx = 0
        pad_right_center_loop:
            mov al, ' ' ; space character
            mov byte [rdx], al
            inc rdx
            inc ecx
            cmp ecx, ebx ; compare with the number of spaces to pad on the right
            jl pad_right_center_loop
        jmp align_done

    pad_center:
        mov rdx, r12 ; rdx = output string
        add rdx, rbx ; rdx = output string + number of spaces to pad
        mov byte [rdx], 0 ; null-terminate
        mov rdx, r12 ; rdx = output string
        mov rcx, r13 ; rcx = input string
        xor eax, eax ; eax = 0
        pad_center_loop:
            mov al, byte [rcx]
            mov byte [rdx], al
            inc rdx
            inc rcx
            cmp byte [rcx - 1], 0 ; check if we reached the end of the input string
            jne pad_center_loop
        xor ecx, ecx ; ecx = 0
        pad_center_right_loop:
            mov al, ' ' ; space character
            mov byte [rdx], al
            inc rdx
            inc ecx
            cmp ecx, ebx ; compare with the number of spaces to pad
            jl pad_center_right_loop
        jmp align_done

    pad_left:
        mov rdx, r12 ; rdx = output string
        add rdx, rbx ; rdx = output string + number of spaces to pad on the left
        mov byte [rdx], 0 ; null-terminate
        mov rdx, r12 ; rdx = output string
        mov rcx, r13 ; rcx = input string
        xor eax, eax ; eax = 0
        pad_left_loop:
            mov al, byte [rcx]
            mov byte [rdx], al
            inc rdx
            inc rcx
            cmp byte [rcx - 1], 0 ; check if we reached the end of the input string
            jne pad_left_loop
        jmp align_done

    align_done:
        pop r13
        pop r12
        pop rbx
        leave
        ret

And this function I call from C:

#include <stdio.h> 
#include <string.h> 
extern void align_str(char *output2, char *input2, unsigned int size, int alignment); 

int main() { 
  char input2[] = "Hello"; 
  char output2[10]; 
  unsigned int size = sizeof(output2); 
  int alignment = 1; 

  align_str(output2, input2, size, alignment); 
} // added by edit

答案1

得分: 3

"对齐" 是什么意思?

  • 左对齐意味着填充位于右侧,而右对齐意味着填充位于左侧。您的代码反过来实现了这一点,并且没有正确实现。例如,pad_right 在终止零后面开始写入空格。这些空格永远不会显示出来!

左对齐

输入:  [My name0]                   长度为7(计算得出)
输出: [.....................]      大小为21(提供的)

填充是大小 - 1 - 长度 = 21 - 1 - 7 = 13
输出: [My name             0]
                <-----13---->;

居中对齐

输入:  [My name0]                   长度为7(计算得出)
输出: [.....................]      大小为21(提供的)

填充是(大小 - 1 - 长度)/ 2 = (21 - 1 - 7)/ 2 = 6
输出: [      My name       0]
         <--6-->       <--7-->;

右对齐

输入:  [My name0]                   长度为7(计算得出)
输出: [.....................]      大小为21(提供的)

填充是大小 - 1 - 长度 = 21 - 1 - 7 = 13
输出: [             My name0]
         <-----13---->;

• 对于左对齐,第一个字符永远不是空格。

• 对于右对齐,最后一个字符永远不是空格。

如果输入的两端包含一个或多个空格字符,任务要求您删除这些空格:

输入:  [  An extra example    0]    长度为16(计算得出)

尽管在这里计算的 StrLen 为22,但去除前导和尾随空格后,长度为16。此外,您现在要复制的字符从 RSI + 2 开始(因为有2个前导空格)。

祝你好运!

英文:

> cmp edi, 0 ; check alignment
> je align_left
> cmp edi, 1
> je align_center
> cmp edi, 2
> je align_right
> ; Invalid alignment value
> jmp align_done
>
> align_left:
> jmp pad_left
> align_center:
> shr ebx, 1 ; divide by 2
> jmp pad_center
> align_right:
> jmp pad_right

What is alignment?

Left-aligning some string in a buffer means that the padding goes on the right, and right-aligning some string in a buffer means the padding goes on the left. Your code does it the other way round and does not implement it correctly. eg. pad_right begins writing spaces behind a terminating zero. Those spaces will never show up!

Left-alignment

Input:  [My name0]                   Length is 7 (calculated)
Output: [.....................]      Size is 21 (provided)

Padding is Size - 1 - Length = 21 - 1 - 7 = 13
Output: [My name             0]
                &lt;-----13----&gt;

Center-alignment

Input:  [My name0]                   Length is 7 (calculated)
Output: [.....................]      Size is 21 (provided)

Padding is (Size - 1 - Length) / 2 = (21 - 1 - 7) / 2 = 6
Output: [      My name       0]
         &lt;--6-&gt;       &lt;--7--&gt;

Right-alignment

Input:  [My name0]                   Length is 7 (calculated)
Output: [.....................]      Size is 21 (provided)

Padding is Size - 1 - Length = 21 - 1 - 7 = 13
Output: [             My name0]
         &lt;-----13----&gt;

> • In case of left alignment, the first character is never a space.

> • In the case of right alignment, the last character is never a space.

Should the input contain one or more space characters on its extremities, the task wants you to remove those:

Input:  [  An extra example    0]    Length is 16 (calculated)

Although here the calculated StrLen is 22, discarding the leading and trailing spaces leads to a length of 16. Also the characters that you will be copying now begin at RSI + 2 (because of the 2 leading spaces).

Good luck!

huangapple
  • 本文由 发表于 2023年6月22日 01:13:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76525686.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定