繁体   English   中英

如果找不到匹配的数据,如何定义一个函数以将指针返回“”值?

[英]How to define a function to return a pointer to a “” value when no matching data is found?

我希望我的function()在错误情况下始终返回“”字符串,否则返回从无符号长整数变量转换为字符串的字符串。

我的初始实现如下:

uint32 cfgVariable_1 = 4;
uint32 cfgVariable_2 = 1;

const char* getCfgVariable (const char* msg)
{
  char* retValue = "";

  if(strcmp("cfgVariable_1", msg)==0)
  {
    // Since I want my function to return a const char* and returning uint32_t is not an option
    sprintf((retValue), "%lu", cfgVariable_1);
    return (const char*)retValue;
  }
  else if(strcmp("cfgVariable_2", msg)==0)
  {
    // Since I want my function to return a const char* and returning uint32_t is not an option
    sprintf((retValue), "%lu", cfgVariable_2);
    return (const char*)retValue;
  }
  else
 {
  //error
 }
 return (const char*) retValue;
}

当在不同的实例上调用该函数以获取cfgVariables时,我期望我的函数getCfgVariable()在找不到匹配项时在错误情况下返回“”。 代码中的某处:

 const char* CfgValue = NULL;

 CfgValue = getCfgVariable("cfgVariable_1");

这里CfgValue指向包含4的位置

后来

 const char* CfgValue = NULL;

 CfgValue = getCfgVariable("cfgVariable_3");

我希望得到一个“”,但我得到4个(CfgValue获取与以前相同的地址)。

由我实施的修复有效,但是我无法理解其背后的逻辑,请修复:

const char* getCfgVariable (const char* msg)
{
  const char* defValue = "";
  char* retValue = "\0";

  if(strcmp("cfgVariable_1", msg)==0)
  {
    // Since I want my function to return a const char* and returning uint32_t is not an option
    sprintf((retValue), "%lu", cfgVariable_1);
    return (const char*)retValue;
  }
  else if(strcmp("cfgVariable_2", msg)==0)
  {
    // Since I want my function to return a const char* and returning uint32_t is not an option
    sprintf((retValue), "%lu", cfgVariable_2);
    return (const char*)retValue;
  }
  else
 {
  //error
 }
 return defValue;
}

我在调试过程中看到defValue和retValue被指向两个不会被覆盖的不同位置。 defValue始终使用“”初始化时指向相同的地址,而retValue使用“ \\ 0”初始化时指向不同的地址。 谁能解释这个背后的逻辑? 我的用例是否有更好的实现?

考虑评论后的解决方案:

const char* getCfgVariable (const char* msg)
{
  const char* retValue = "";
  std::ostringstream oss;

  if(!strcmp("cfgVariable_1", msg))
  {
    oss << cfgVariable_1;
  }
  else if(!strcmp("cfgVariable_2", msg))
  {
    oss << cfgVariable_2;
  }
  else
  {
    //error
    return retValue;
  }
  const std::string tmp = oss.str();
  retValue = tmp.c_str();

  return retValue;
}

到目前为止,感谢您的评论,此解决方案仍然可以接受进一步的改进建议。

Constexpr字符串,例如“ \\ 0”,“”,“ cfgVariable_1”等。这些是内存中的常量字符串,已编译为最终的可执行文件。 试图将值写入这些字符串非常危险! 在旧样式C中,您必须使用malloc分配一些内存以用于您的字符串。 这是在实践中处理的真正痛苦(对于学习C ++的人来说并不理想)。

一个简单得多的解决方案是开始使用C ++字符串对象std :: string(它为您处理所有动态内存分配!)。 这样可以将您的问题减少到更简单一些(最重要的是,更安全!):

#include <string>
#include <sstream>

std::string getCfgVariable (const char* const msg)
{
  std::ostringstream oss;
  if(!strcmp("cfgVariable_1", msg))
  {
    oss << cfgVariable_1;
  }
  else 
  if(!strcmp("cfgVariable_2", msg))
  {
    oss << cfgVariable_2;
  }
  return oss.str();
}

在C中执行此操作,您有2个选择。 为返回的字符串分配内存,或使用始终可用的静态缓冲区(此示例将执行此操作)。

uint32 cfgVariable_1 = 4;
uint32 cfgVariable_2 = 1;

const char* getCfgVariable (const char* msg)
{
  static char retValue[32] = {0};

  if(strcmp("cfgVariable_1", msg)==0)
  {
    // Since I want my function to return a const char* and returning uint32_t is not an option
    sprintf(retValue, "%lu", cfgVariable_1);
    return retValue;
  }
  else if(strcmp("cfgVariable_2", msg)==0)
  {
    // Since I want my function to return a const char* and returning uint32_t is not an option
    sprintf(retValue, "%lu", cfgVariable_2);
    return retValue;
  }
  else
 {
  //error
 }
 return retValue;
}

但是,因为现在retValue是固定在内存中的数组,所以返回的字符串仅在下一次调用getCfgVariable之前才有效,这可能有点奇怪。

const char* A = getCfgVariable("cfgVariable_1");
printf("%s\n", A); // prints '4'

const char* B = getCfgVariable("cfgVariable_2");
printf("%s\n", B); // prints '1'
printf("%s\n", A); // now this will print '1', and not '4'. 

const char* C = getCfgVariable("anythingElse");
printf("%s\n", C); // prints ""
printf("%s\n", B); // prints ""
printf("%s\n", A); // aso prints ""

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM