英文:
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]
<-----13---->
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]
<--6-> <--7-->
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]
<-----13---->
> • 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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论