【问题标题】:how to access an array of strings in a loop to store a string into the array according如何在循环中访问字符串数组以将字符串存储到数组中
【发布时间】:2019-05-04 20:09:53
【问题描述】:

我的问题是我试图在循环中获取用户输入,并且每次我想将该输入存储到内存中的某个位置以便稍后访问它并进行一些更改后打印它。而且我很困惑如何首先声明一个可以容纳我的 5 个单词的数组,然后如何将每次输入的输入存储到该数组中。

正是我正在取主题的名称:c++ 中的循环看起来像这样:

string subjects_code[5]
for(int i=0; i<5; i++)
    cin>>subjects_code[i];   
   // like AFJS421 , CSFA424, SCSJ1023 and so on

我在整个互联网和 YouTube 上进行了研究,我发现你不能在汇编中声明一个字符串数组,你基本上只有一个字节数组,后跟一个空终止符。我明白这一点,我用它做了我的代码,它正在工作,但问题是我真的需要将 5 个主题代码存储到 5 个不同的变量(或至少是内存位置)中,因为稍后经过一些计算我需要打印回来那些科目。

    ;taking input from user: in a Loop   
    ;in .data I have subjects_code BYTE MAX DUP(?)
    MAX = 20
mov ebx,0
mov count, 5   ; cuz ReadString uses ecx as buffersize

InputLoop:
            ; This is just a prompt out, no need to worry about it

    mov ecx, MAX    
    mov edx, OFFSET Enter_code       ;  setting offset for prompt   


            ; temp variable to read into it, use it for assgining
    mov edx, OFFSET temp_subject_code  
    call ReadString                 ; reading the code into temp
    mov subjects_code+[ebx], temp_subject_code


    add ebx, 4
    mov ecx, count
    dec count

    Loop InputLoop

;---------------------------------------------------------------

存储每个字符串后,我希望在程序结束时做:

subject1: SCSJ134
subject2: SCSR231
Subject3: SCSI392

一直到Subject5

【问题讨论】:

  • C++ 字符串和汇编字符串之间的主要区别在于,在 C++ 中,编译器和/或运行时库管理字符串的内存并根据需要分配/复制内存。编写汇编代码时,您必须自己处理这些细节。您不能简单地将一个字符串分配给另一个字符串,您必须编写代码来实际计算位置并复制字节。在这方面,C 比 C++ 更接近于汇编语言的功能,因此您可能需要考虑使用 C 代码而不是 C++ 作为汇编代码的原型,以便正确执行步骤。

标签: assembly x86


【解决方案1】:

这是一种方法。这相当于 C 代码:

char subject_code[5][20];
for(int i=0; i<5; i++)
    ReadString(subject_code[i]);

.

    MAXLEN = 20
    COUNT = 5
    mov ebx,0

InputLoop:
    mov eax, MAXLEN
    mul ebx
    lea edx, subjects_code[eax]  
    mov ecx, MAXLEN-1
    call ReadString                 ; reading the code into subject_code[ebx]

    inc ebx
    cmp ebx, COUNT
    jnz InputLoop

    mov ebx, 0
OutputLoop:
    mov ecx, MAXLEN
    mov eax, ebx
    mul ecx ; this can be done without mul since MAXLEN is a constant
    lea edx, subjects_code[eax]
    call WriteString
    call Crlf

    inc ebx
    cmp ebx,COUNT
    jl OutputLoop

    .data
subjects_code BYTE MAXLEN*COUNT DUP(?)

【讨论】:

  • 我尝试了这段代码,它适用于输入,而对于输出,它通过打印内存中的随机内容并在稍后破坏 OutputLoop 时出错:mov ecx,MAXLEN mov eax,ebx mul ecx lea edx, subject_code[eax] 调用 WriteString inc ebx cmp ebx, COUNT jnz OutputLoop
  • 我又试了一次:效果很好 mov ebx, 0 OutputLoop: mov ecx, MAXLEN mov eax, ebx mul ecx ;这可以在没有 mul 的情况下完成,因为 MAXLEN 是一个常量 lea edx,subjects_code[eax] call WriteString call Crlf inc ebx cmp ebx,COUNT jle OutputLoop
  • 根据您对另一个答案的评论,我在调用 ReadString 之前添加了“mov ecx,MAXLEN-1”,以避免缓冲区溢出的可能性。
  • 为了方便未来的读者,我将工作输出循环添加到答案中。谢谢你分享。我将jle 更改为jl,以避免超出数组末尾。 (该错误可能在您的输出中显示为一个额外的空白行。)
【解决方案2】:

这是另一种方法。这相当于 C 代码:

char *subject_code[5];
for(int i=0; i<5; i++) {
    subject_code[i] = malloc(20);
    ReadString(subject_code[i]);
}

.

    MAXLEN = 20
    COUNT = 5
    mov ebx,0

InputLoop:
    mov ecx, MAXLEN
    call malloc
    mov subjects_code[ebx*4], eax
    mov edx, eax  
    mov ecx, MAXLEN
    call ReadString                 ; reading the code into subject_code[ebx]

    inc ebx
    cmp ebx, COUNT
    jnz InputLoop

    .data
subjects_code DWORD COUNT DUP(?)

【讨论】:

  • 请注意,我省略了诸如错误检查之类的细节。我不知道 ReadString 是空终止字符串还是返回读取的字符数,但如果是后者,那么你会想要存储它。
  • 对于这种方法,它告诉我没有定义 Malloc,我正在使用 VisualStudio 2010 进行编译(这是编译的唯一方法),我正在使用 Include Irvine32.inc
  • 我也用谷歌搜索了读取字符串,我得到了这个:从标准输入中读取最多 ECX 非空字符的字符串,当用户按下 Enter 键时停止。在字符输入之后存储一个空字节,但尾随回车和换行字符不会放入缓冲区。 ECX 应始终小于缓冲区大小(从不等于缓冲区大小),因为空字节可能是存储的第 (ECX+1) 个字符。
  • 抱歉,我使用“malloc”作为占位符来表示任何可用的内存分配函数。我猜你会使用 HeapAlloc 吗?您需要了解调用顺序是什么;我没用过。
猜你喜欢
  • 2014-09-02
  • 1970-01-01
  • 2010-10-13
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-14
  • 2021-03-28
相关资源
最近更新 更多