【问题标题】:How to return a string from a function, while the string is in an array如何从函数返回字符串,而字符串在数组中
【发布时间】:2019-09-20 09:24:04
【问题描述】:

我正在编写一个游戏,我必须将一个单词存储在一个数组中,然后函数返回该单词。 在我的例子中,单词是“control”,数组名是mot_generer,函数名是initialisation_mot_a_trouver

我尝试使用代码返回mot_generer,但我的错误代码如下:

jeu_pendu.c:在函数“initialisation_mot_a_trouver”中: jeu_pendu.c:82:10:警告:return 从指针中生成整数而无需强制转换 [-Wint-conversion] 返回 mot_generer;

char initialisation_mot_a_trouver(){  
    char mot_generer[]="controle";  
    return mot_generer;
}

【问题讨论】:

  • 你不能,因为字符串是一个局部变量,当函数返回时不再存在。使用malloc
  • 此外,该函数返回一个字符,但您返回一个字符数组。声明为char *init..
  • 我认为这个问题已经解决了here
  • 如果您实际上有一个由字符串常量初始化的数组,您可以将局部变量设置为静态变量。这是答案中提到的另一种方法,它告诉您返回一个必须是free()ed 的堆对象。您可以更改函数签名以返回const char*,然后返回static char mot_generer[] = "initialized-with-a-compile-time-defined-string";

标签: c arrays scope c-strings lifetime


【解决方案1】:

见我的 cmets。正确的版本是:

char *initialisation_mot_a_trouver()
{  
    char *mot_generer= malloc(strlen("controle")+1);
    strcpy(mot_generer, "controle");
    return mot_generer;
}

调用者必须free()返回的字符串。

【讨论】:

    【解决方案2】:

    函数有两个错误。

    第一个是表达式中的数组被隐式转换为指向数组元素类型的指针。

    所以如果函数有返回表达式

    return mot_generer;
    

    如果mot_generer 是一个数组,那么函数的返回类型应该是char *

    第二个错误是函数(正确声明)返回指向具有自动存储持续时间的本地数组的指针,退出函数后将不再存在。

    所以要么在函数中声明数组具有静态存储持续时间,如

    char * initialisation_mot_a_trouver(){  
    
        static char mot_generer[]="controle";  
    
        return mot_generer;
    }
    

    或者像动态分配数组

    char * initialisation_mot_a_trouver()
    {
        const char *literal = "controle";
    
        char *s = malloc( strlen( literal ) + 1 );
    
        if ( s != NULL ) strcpy( s, literal );
    
        return s;
    }
    

    第三种方法是将 main 中已经创建的数组传递给函数。

    在这种情况下,函数看起来像

    char * initialisation_mot_a_trouver( char s[], size_t n )
    {
        strncpy( s, "controle", n );
        s[n -1] = '\0';
    
        // or for example
        // fgets( s, n, stdin );
        // s[ strcspn( s, "\n" ) ] = '\0'; 
    
        return s;
    }
    

    【讨论】:

      【解决方案3】:

      你的函数说它会返回一个字符,但实际上你返回的是一个字符*。

      char* initialisation_mot_a_trouver(){  
      
          char mot_generer[]="controle";  
      
          return mot_generer;
      
      }
      

      但是我不返回本地堆栈地址,因为它们在应用程序的执行过程中很容易改变。 更好地使用堆地址:

      char* initialisation_mot_a_trouver(){  
          char mot_generer[]="controle";
          char *pszNamePtr = calloc(strlen(mot_generer) + 1, sizeof(char));
          strncpy(pszNamePtr, mot_generer, strlen(mot_generer);
      
          return pszNamePtr;
      
      }
      

      或者查看 Paul Ogilvie 的答案以了解另一种方法。

      【讨论】:

      • 1) 不需要 calloc; 2)不要强制转换malloc的返回值; 3) sizeof(char) 始终为 1; 4)不需要strncpy(然后你应该总是设置终止null)
      • 返回指向局部变量的指针不仅“不推荐”而且明显是错误的。
      • @PaulOgilvie 1) 需要什么,什么不利于我,或者你可以通过多种方式实现目标的操作 3) 仍然没有错 4) 与 1) 相同 + 使用 calloc 我不必设置它,我确保数据初始化为零。但我很欣赏你的 2)
      • @Trickzter 您对strncpy 的看法是正确的,对不起,我的错,但解决方案不仅必须正常工作(就像您的那样),而且还应该简单高效。将您臃肿的容易出错的代码与 Paul Ogilvie 的简单代码进行比较。
      • ad 1) calloc 返回归零的内存。不需要将内存归零;没有任何好处(只是更多的机器周期将内存归零)。广告 3) 只需键入更多字符而没有明显的好处。 4)内存被精确分配。无需使用限制功能。如前所述,如果您使用它,然后正确使用它并始终放入零终止符。也不需要调用 strlen,而且只会花费更多的周期。
      猜你喜欢
      • 1970-01-01
      • 2022-10-14
      • 2013-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 2010-12-23
      相关资源
      最近更新 更多