我正在构建快速的“配置阅读器”,它从文件中读取设置。 问题是,该函数返回“800”字符串,atol与该输入返回0.我不确定我做错了什么。
所以,这就是它大致的样子:
char *txtval=GetParamFromLine("WINDOW_WIDTH");
val = atol(txtval);
char* GetParamFromLine(char*parameter)
{
char text[16];
//
// do the reading procedure and fill the text
//
return text;
}
结果:atol(文本)= 0(其中text =“800”)
感谢您的帮助!
答案 0 :(得分:4)
你需要有"文字"存储在堆而不是堆栈中。否则,当函数结束时,变量将超出范围,并且您将尝试访问该段内存时出现未定义的行为。您可以在堆上分配内存,然后在完成后释放它,
char *txtval=GetParamFromLine("WINDOW_WIDTH");
val = atol(txtval);
free txtval;
// Caller is responsible for freeing returned buffer
char* GetParamFromLine(char*parameter)
{
char text* = malloc(sizeof(char)*16);
//
// do the reading procedure and fill the text
//
return text;
}
或者,也可以将指针传递给应该存储结果的缓冲区。
char txtval[16];
GetParamFromLine("WINDOW_WIDTH", txtval);
val = atol(txtval);
void GetParamFromLine(char *parameter, char *resultBuffer)
{
//
// do the reading procedure and fill the text into resultBuffer
//
}
答案 1 :(得分:3)
您正在返回指向本地范围变量的指针。在函数调用之后,内存text
超出了范围,因此指向它的指针没有意义,因为内存将被回收...
您需要为text
分配一些长期存储空间,或将GetParamFromLine
和atol
合并到同一个功能中。
答案 2 :(得分:2)
将文字设为静态:
char* GetParamFromLine(char*parameter)
{
static char text[16];
... do something
return text;
}
您的版本使用的是堆栈驻留版本,在使用之前可能会被覆盖。
确保静态存储类说明符返回缓冲区只有在下次调用GetParameterFromLine之前才会有效。
通常,调用者最好提供缓冲区和缓冲区大小作为这样的函数的参数。
char *GetParamFromLine(const char *parameter, char *text, size_t text_size)
{
... do something
return text;
}
“做某事”代码应该仔细观察这个大小。您必须决定是否截断参数,返回空字符串,返回NULL指针,或者如果实际数据长于缓冲区,则返回任何内容。
答案 3 :(得分:2)
问题是由返回指向局部变量的指针引起的。当函数GetParamFromLine
返回时,变量text
超出范围。返回的指针不再有效,导致未定义的行为。您必须以其他方式返回数据,例如:
std::string txtval=GetParamFromLine("WINDOW_WIDTH");
val = atol(txtval.c_str());
std::string GetParamFromLine(char*parameter)
{
char text[16];
//
// do the reading procedure and fill the text
//
return std::string(text);
}
将返回类型从指向本地的指针更改为std::string
可以缓解返回指向局部变量的指针的问题。 std::string
使用的资源由对象管理,并自动清理。
作为替代方案,您也可以删除atol
来电并改为使用std::istringstream
。一个好处是,这可以更好地报告错误:
std::string txtval=GetParamFromLine("WINDOW_WIDTH");
std::istringstream iss(txtval);
int val( 0 );
iss >> val;
现在,如果你真的想要超越顶部,你可以将字符串的检索和转换结合到一个整数数据类型,并参数化这个新函数模板的返回类型:
template<typename T>
T GetValueFromLine(const std::string& param) {
std::string txtval=GetParamFromLine(param.c_str);
std::istringstream iss(txtval);
T val = T();
iss >> val;
return val;
}
使用此模板,您可以执行以下操作:
long wndWidth = GetValueFromLine<long>("WINDOW_WIDTH");
bool showInfo = GetValueFromLine<bool>("SHOW_INFO");
....
注意:错误处理已被忽略。