【问题标题】:Modifying arrays of strings in C in another function在另一个函数中修改 C 中的字符串数组
【发布时间】:2013-11-24 06:02:48
【问题描述】:

我正在尝试为 RiSC CPU 编写一个汇编程序,可笑的是简单的计算机 - 可以在此处找到更多信息 - Link to CPU information

我用 C 语言编程已经有一段时间了,但我遇到了一个问题。我的汇编程序的第一步是找到所有标签并记下它们的位置,现在我正在尝试创建一个仅包含标签名称的数组,以及一个包含它们将指向的 asm 行的单独数组到。

我有以下函数可以解析一行汇编代码并找到标签:

int lcount=0;
int lineCount = 0;
char *  BuildLabels(char * line, FILE *in, char *Labels[], char *LabelVals[])
{
    char lineString = fgets(line,MAX_LENGTH,in);
    if(lineString!=NULL)
    {
        char * FirstToken = strtok(line," \t\n");
        if(FirstToken[0]!='#' || FirstToken != NULL)
        {
            if(FirstToken[strlen(FirstToken)-1]==':')
            {
                Labels[lcount] = FirstToken;
                LabelVals[lcount] = lineCount;
                printf("%s : %d\n",Labels[lcount],lcount);
                lcount++;
            }
          lineCount++;
        }
    return Labels[lcount];
   }else
       {
           return NULL;
       }
}

main中的这段代码正在调用该函数

char *Labels[NUM_LABELS];
char *LabelVals[NUM_LABELS];
while(BuildLabels(lineString,input,Labels,LabelVals)!=NULL)
{

}
printf("%s:%s\n",Labels[0],Labels[1]);
printf("Exiting Now...\n");

当我运行这个程序时,我得到以下输出

Opening input...
Opening output...
start::0
done::1
count::2
neg1::3
startAddr::4
startAddr::startAddr:
Exiting Now...

Process returned 0 (0x0)   execution time : 0.009 s
Press any key to continue.

所以..数组在函数中发生了变化,但它们在主函数中不受影响? 我希望最后一行是 start::done: 而不是 startAddr::startAddr。

我觉得这很奇怪,所以我编写了以下函数,当我尝试打印 Labels[0] 和 Labels1 时,它按预期改变了被调用函数和 main 中的字符串

void Testing(char *Labels[])
{
    lcount = 0;
    Labels[lcount] = "Testing";
    lcount++;
    Labels[lcount] = "Double Testing";
}

当我从 main 调用此函数然后尝试打印 Labels[0] 和 Labels1 时,它会打印出“Testing:Double Testing”

我不明白为什么之前的函数不能正常工作 - 这也不是功课,我想了解更多关于编译器/汇编器的信息,因为我习惯于使用 Verilog/VHDL 工作。

感谢任何帮助!

编辑:这最终成为我的解决方案,有人可以向我解释为什么这样做吗?

Labels[lcount] = malloc(strlen(FirstToken)+1);
strcpy(Labels[lcount],FirstToken);

【问题讨论】:

  • lcountlinecount 是全局定义的吗?

标签: c arrays string function pointers


【解决方案1】:

我不确定这是你的根本问题,但在这一行

char lineString = fgets(line,MAX_LENGTH,in);  

您正在尝试将字符串存储到 char 类型变量。
改成

char *lineString; 

并为lineString 分配内存。

lineString = malloc(Size_You_want_to_allocate); //50 byte or 100 bytes or even more.  
lineString = fgets(line,MAX_LENGTH,in);   

也要改

if(lineString!=NULL)  

if(lineString!=NUL)

【讨论】:

  • 我将如何为这样的事情分配内存?我有点困惑,因为我需要从文件流中读取该命令
  • 编辑了我的答案。如果这对您来说很困难,那么只需执行以下操作:char lineString[100] = fgets(line,MAX_LENGTH,in);.
  • 不幸的是,当我更改函数中的代码以手动将字符串分配给数组值时,它不起作用,例如if(lcount ==1){Labels[lcount] == "one"}.. 和 2,3,4 等相同的代码,它工作得很好!好奇怪
  • 仍然没有运气,这部分代码似乎正在工作,它将值分配给 Labels[] 数组,这让我非常困惑。
【解决方案2】:

您的大部分问题似乎来自“字符串”一词,您似乎对此有些困惑。这并不奇怪,因为 C 语言中“字符串”的概念有些模糊,它可以表示多种不同的东西。

“字符串”可以是像"foobar" 这样的字符串文字,它是静态内存中的字符序列,以空字符结尾。

“字符串”也可以是像char foobar[SIZE]; 这样的字符数组,它声明了一个数组,可用于保存以空字符结尾的字符序列。

或者,“字符串”是指向上述任何一种字符串的字符指针 (char *)。

在许多情况下,上述任何字符串都可以互换使用。在其他情况下,它们之间的区别很重要。

让我们看看你的代码,看看它做了什么。你有:

while(BuildLabels(lineString,input,Labels,LabelVals)!=NULL)

这会在循环中调用函数BuildLabelsBuildLabels 的声明是

char * BuildLabels(char * line, FILE *in, char *Labels[], char *LabelVals[])

所以第一个参数是第三种意义上的字符串。您没有显示lineString 的声明,但根据您报告的结果,它可能类似于

char lineString[MAX_LENGTH];

第二种意义上的字符串。

因此,您声明一个字符数组来保存一个字符串,然后将指向该字符串的指针(在循环中)传递给 BuildLabels。因此,在每次调用中,line 将指向同一个字符串数组,这意味着在入口处它将包含上一次调用的数据,并将用自己的数据覆盖该数据。

BuildLabels 中,您调用fgets(line,,它将一行读入该数组(请记住,您传递一个指向eash 时间的指针的同一数组lineString),然后strtok(line, 将字符串拆分到位成令牌。那么当你这样做时

Labels[lcount] = FirstToken;

您将指向同一数组的指针存储到Labels 数组中。 Labels,作为指针数组是第三个意义上的字符串数组,因此实际上并不保存字符串的字符,只是指向其他缓冲区的指针。然后,该缓冲区将被下一次调用BuildLabels 覆盖,从而更改Labels 数组中的指针指向的字符串。所以回到main,当你去打印Labels[0]Labels[1]时,它会打印最后一次调用BuildLables的缓冲区中的字符,而不是你进行指针分配时缓冲区中的字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-29
    • 2023-01-10
    • 2020-05-18
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 2018-10-10
    • 2021-08-08
    相关资源
    最近更新 更多