【发布时间】:2010-10-26 14:38:50
【问题描述】:
我是 C++ 编程的新手,我一直在尝试从 const char* 转换为 unsigned int,但没有成功。 我有一个:
const char* charVar;
我需要将其转换为:
unsigned int uintVar;
如何在 C++ 中完成?
谢谢
【问题讨论】:
-
-1 不清楚您在此处使用 convert 是什么意思。你尝试了什么?
标签: c++
我是 C++ 编程的新手,我一直在尝试从 const char* 转换为 unsigned int,但没有成功。 我有一个:
const char* charVar;
我需要将其转换为:
unsigned int uintVar;
如何在 C++ 中完成?
谢谢
【问题讨论】:
标签: c++
#include <iostream>
#include <sstream>
const char* value = "1234567";
stringstream strValue;
strValue << value;
unsigned int intValue;
strValue >> intValue;
cout << value << endl;
cout << intValue << endl;
输出:
1234567
1234567
【讨论】:
转换是什么意思?
如果您正在谈论从文本中读取整数,那么您有多种选择。
提升词法转换:http://www.boost.org/doc/libs/1_44_0/libs/conversion/lexical_cast.htm
字符串流:
const char* x = "10";
int y;
stringstream s(x);
s >> y;
或者不错的旧 C 函数 atoi() 和 strtol()
【讨论】:
如果您真的想将指向常量字符的指针转换为无符号整数,那么您应该在 c++ 中使用:
const char* p;
unsigned int i = reinterpret_cast<unsigned int>( p );
这会将指针指向的地址转换为无符号整数。
如果要将指针指向的内容转换为无符号整数,应使用:
const char* p;
unsigned int i = static_cast<unsigned int>( *p );
如果您想从字符串中获取整数,从而将 const char* 解释为指向 const char 数组的指针,则可以使用上述解决方案之一。
【讨论】:
C 方式:
#include <stdlib.h>
int main() {
const char *charVar = "16";
unsigned int uintVar = 0;
uintVar = atoi(charVar);
return 0;
}
C++ 方式:
#include <sstream>
int main() {
istringstream myStream("16");
unsigned int uintVar = 0;
myStream >> uintVar;
return 0;
}
请注意,在这两种情况下,我都没有检查转换的返回码以确保它确实有效。
【讨论】:
在 C 中,这可以使用 atoi 完成,C++ 也可以通过 cstdlib 使用。
【讨论】:
atoi("blah") 返回什么?这与atoi(0) 有何不同?
atoi() 可能是所有可用选项中最糟糕的选择。
atoi 是否不好取决于您的用例。首先,它是迄今为止所有解决方案中最短的。另一方面,它不进行错误检查。所以这真的只是我经常发现有用的一种快速而肮脏的方法。
我通常使用这个通用函数将字符串转换为“任何东西”:
#include <sstream>
// Convert string values into type T results.
// Returns false in case the conversion fails.
template <typename T>
bool getValueFromString( const std::string & value, T & result )
{
std::istringstream iss( value );
return !( iss >> result ).fail();
}
只需像这样使用它:
int main()
{
const char * a_string = "44";
unsigned int an_int;
bool success;
// convert from const char * into unsigned int
success = getValueFromString( a_string, an_int );
// or any other generic convertion
double a;
int b;
float c;
// conver to into double
success = getValueFromString( "45", a );
// conve rto into int
success = getValueFromString( "46", b );
// conver to into float
success = getValueFromString( "47.8", c );
}
【讨论】:
getValueFromString("-123", an_int),success 也将等于 0,并且您将在 an_int 中获得垃圾值。
an_int 被声明为unsigned int,因此您不能为其分配负数。并且存储在 an_int 中的不是“垃圾”,而是 -123 的 2 的补码表示。
atoi 函数会将 const char* 转换为 int,可以隐式转换为 unsigned。这不适用于不适合 int 的大整数。
更 C++ 的方式是使用字符串和流
#include <sstream>
#include <string>
int main()
{
std::string strVar;
unsigned uintVar;
std::istringstream in(strVar);
in >> uintVar;
}
一种更简单但非标准的方法是使用 boost 的 lexical cast。
HTH
【讨论】:
所以我知道这已经过时了,但我想我会提供一种更有效的方法来做这件事,这将使你在你想要的基础上有一些灵活性。
#include<iostream>
unsigned long cstring_to_ul(const char* str, char** end = nullptr, int base = 10)
{
errno = 0; // Used to see if there was success or failure
auto ul = strtoul(str, end, base);
if(errno != ERANGE)
{
return ul;
}
return ULONG_MAX;
}
这将做的是围绕 C 中的 strtoul(const char* nptr, char** endptr, int base) 方法创建一个包装器。有关此函数的更多信息,您可以在此处阅读手册页中的描述@ 987654321@
如果失败,您将获得 errno = ERANGE,这将允许您在调用此函数后进行检查,并且值为 ULONG_MAX。
使用它的示例如下:
int main()
{
unsigned long ul = cstring_to_ul("3284201");
if(errno == ERANGE && ul == ULONG_MAX)
{
std::cout << "Input out of range of unsigned long.\n";
exit(EXIT_FAILURE);
}
std::cout << "Output: " << ul << "\n";
}
这将给出输出
输出:3284201
【讨论】:
如果没有更多信息,就无法正确回答这个问题。你想确切地转换什么?如果 charVar 是字符串的 ascii 表示,那么您可以像其他人建议的那样使用 stringstreams、atoi、sscanf 等。
如果你想要 charVar 所指向的实际值,那么你会想要类似的东西:
intValue = (unsigned int)(*charVal);
或者如果 charVal 是指向无符号整数第一个字节的指针,则:
intValue = *((unsigned int*)(charVal));【讨论】:
const char* charVar = "12345";
unsigned int uintVar;
try {
uintVar = std::stoi( std::string(charVar) );
}
catch(const std::invalid_argument& e) {
std::cout << "Invalid Arg: " << e.what() << endl;
}
catch(const std::out_of_range& e) {
std::cout << "Out of range: " << e.what() << endl;
}
【讨论】:
您也可以使用strtoul 或_tcstoul 从const char* 获取无符号长整型值,然后将该值转换为无符号整数。
http://msdn.microsoft.com/en-us/library/5k9xb7x1(v=vs.71).aspx
【讨论】:
const char* charVar = "1864056953";
unsigned int uintVar = 0;
for (const char* it = charVar; *it != 0; *it++){
if ((*it < 48) || (*it > 57)) break; // see ASCII table
uintVar *= 10; // overflow may occur
uintVar += *it - 48; //
}
std::cout << uintVar << std::endl;
std::cout << charVar << std::endl;
【讨论】:
'0'而不是48和'9'而不是57你就不会依赖ASCII。
*it++ 中* 无效。 it++ 就足够了(我实际上会使用++it)。最后,uintVar < 0 比较没有意义,因为您的数据类型是 unsigned。
*it++ 没有意义。你增加指针然后你取消引用它,但你没有对你得到的值做任何事情。
这样试试
#include<iostream>
#include <typeinfo> //includes typeid
using namespace std;
int main(){
char a = '3';
int k = 3;
const char* ptr = &a;
cout << typeid(*ptr).name() << endl; //prints the data type c = char
cout << typeid(*ptr-'0').name() << endl; //prints the data type i = integer
cout << *ptr-'0' << endl;
return 0;
}
【讨论】: