使用 strcpy 将字符串复制到使用 atoi 检索的索引处的元素中

Posted

技术标签:

【中文标题】使用 strcpy 将字符串复制到使用 atoi 检索的索引处的元素中【英文标题】:using strcpy for copying string into the element at index retrieved with atoi 【发布时间】:2013-02-24 12:26:28 【问题描述】:

下面是代码,当输入“history 1”时,它应该执行history中的第一个命令:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[])

    int i=0; int j=0; int k=0;
    char inputString[100];
    char *result=NULL;
    char delims[] = " ";
    char historyArray[100][100] = 0;
    char *tokenArray[100][100] ;

    do
    
        j = 0;
        printf("hshell>");
        gets(inputString);
        strcpy (historyArray[k], inputString);
        k++;

        // Break the string into parts
        result = strtok(inputString, delims);

        while (result!=NULL)
        
            //result2 = result;
            strcpy(tokenArray[j], result);
            //puts(result);
            j++;
            result= strtok(NULL, delims);                  
            //puts(tokenArray[j]);     
        
        //j = 0;
        puts(tokenArray[0]);
        puts(tokenArray[1]);

        if (strcmp(tokenArray[0], "exit") == 0)
        
            return 0;
        
        else if (strcmp(tokenArray[0], "history") ==  0)
        
           if (j>1)
           
              strcpy (result,historyArray[atoi(tokenArray[j-1])]);

           
           else
           
               //print history array
               for (i=0; i<k;i++)
                   printf("%i. %s\n", i+1, historyArray[i]);
           
        
        else
        
          printf("Command not found\n");
        
    while (1);

但是,它崩溃了。在调试时,我注意到两件事: - 数组 (tokenArray) 地址超出范围 和 - 访问冲突(分段错误)。您可以在下图中看到错误。

我错过了什么?我做错了什么?

【问题讨论】:

我认为应该是char tokenArray[100][100],即没有* 还要注意historyArray[atoi(tokenArray[j-1])]是相当危险的...而且atoi不是标准C的一部分,请改用sscanf(tokenArray[j-1], "%d", &amp;index)并检查它的返回值是否为1(意思是真正读取了 1 个整数),然后只需访问 historyArray[index] :) 我应该在哪里使用sscanf(tokenArray[j-1], "%d", &amp;index)?我还是这门语言的新手。可以举个例子吗? @cnicutar 试过了。警告消失了,但它仍然崩溃。 @LihO atoi 是标准 C。你正在考虑 itoa 【参考方案1】:

您处理分段错误的原因是因为您试图将字符串复制到尚未分配的内存中。您已将 result 定义为 char* 并仅将 NULL 分配给它,因此尝试将字符串复制到其中是错误的:

char *result = NULL;
// ...
strcpy(result, historyArray[atoi(tokenArray[j-1])]);

您需要分配一些内存,result 将指向。然后strcpy 可以用来将字符串复制到这个内存中。您可以使用malloc 动态分配它,也可以将result 定义为具有自动存储持续时间的临时变量(即char result[100];)。


还要注意

char *tokenArray[100][100];

定义一个指向char 的二维指针数组。但是在这种情况下你真正需要的是一个字符串数组,所以你需要摆脱*,就像@cnicutar 指出的那样。


还有一点:

strcpy(result,historyArray[atoi(tokenArray[j-1])]);

这样做是很危险的,因为当atoi 失败时,你试图访问数组边界之外的元素,这会产生未定义的行为,因此我建议你这样做:

char tokenArray[100][100] = 0;

int index;
char indexString[100] = "8";
if (sscanf(indexString, "%d", &index) == 1)     // integer successfully retrieved

    strcpy(tokenArray[index], "some string");
    printf("%s", tokenArray[8]);

【讨论】:

我使用这个strcpy(hCommand,historyArray[tempIndex-1]); 尝试复制historyArray 中的第一个命令在hCommand variable. I declared the hCommand` 中,如下所示:char hCommand[1][20];。它产生了 array subscript is not an integer 。任何想法为什么? @voth1234:这意味着tempIndex的类型应该是int 错过了 :) 谢谢。编辑:这样做,编译。现在它崩溃了 (Segmentation Fault) 作为上一行 strcpy (tempIndex,tokenArray[1]); @voth1234:您应该学习如何使用调试器。还要确保您始终了解您的代码在做什么,尤其是在涉及内存管理时。您应该知道分配的时间和内容,如何使用它,您是否负责释放它,如果是,那么如何...如果您遇到无法自己解决的问题,那么将其作为一个新问题提出。只要确保您首先付出自己的努力即可:)【参考方案2】:

您可能是指char tokenArray[100][100];,它创建100 tokens,每个令牌中都有100 个字符。

写作char *tokenArray[100][100]字面意思是tokenArray是一个100数组的数组,其中包含100char *。但是如果没有分配正确的地址,每个char * 都会指向一个随机地址。

您收到分段违规错误,因为其中一个 char * 包含您无法访问的地址。

【讨论】:

以上是关于使用 strcpy 将字符串复制到使用 atoi 检索的索引处的元素中的主要内容,如果未能解决你的问题,请参考以下文章

strcpy 与 strdup

c语言strcpy将一个结构体的数据复制到另一个后,出问题了

编写一个程序,将字符数组s2中的全部字符复制到字符数组s1中,不用strcpy函数。复制时,‘

strcpy函数问题

字符串小技巧

如何strcpy并返回复制的字符数?