2013-03-18 179 views
-1

我试图将指针转换为字符串,并将字符串转换为使用以下代码的指针(词法转换)。从指针到字符串的转换工作正常,但不是相反。将字符串转换为指针

这是为什么发生? 有没有其他方法可以将字符串转换为指针?

我并不担心由不正确的字符串格式造成的错误。我试图转换为指针的字符串将始终通过将指针转换为字符串来生成。

下面的代码:

//TB_ConvertToString.cpp 

#include<iostream> 
#include<cstdio> 
#include<sstream> 
#include<string> 

//Functions to convert data types to and from strings 
template <typename T> std::string ToString (T Number) 
{ 
    std::stringstream ss; 
    ss << Number; 
    return ss.str(); 
}; 

template <typename T> 
T FromString (const std::string &Text) 
{ 
    std::stringstream ss(Text); 
    T result; 
    ss >> result; 
    return result; 
} 
//------------------------------------------------- 


using namespace std; 

int main() 
{ 
    int a =10; 
    int* p1 = &a; 
    // this works------------ 
    string s1 = ToString<int *>(p1); 
    printf("\n ptr: %s",s1.c_str()); 
    //---------------------- 

    //this gives compilation errors ----- 
    //int * p2 = FromString<int *>(s1); 
    //printf("\n ptr: %p",p2); 
    //---------------------- 


    cout<<"\n\n"; 
    return 0; 
}; 

取消注释的问题部分提供了以下编译错误:

[email protected]:~/Desktop$ g++ TB_ConvertToString.cpp 
TB_ConvertToString.cpp: In function ‘T FromString(const string&) [with T = int*, std::string = std::basic_string<char>]’: 
TB_ConvertToString.cpp:39:33: instantiated from here 
TB_ConvertToString.cpp:21:2: error: no match for ‘operator>>’ in ‘ss >> result’ 
TB_ConvertToString.cpp:21:2: note: candidates are: 
/usr/include/c++/4.6/istream:122:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _Traits>::__istream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:122:7: note: no known conversion for argument 1 from ‘int*’ to ‘std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&) {aka std::basic_istream<char>& (*)(std::basic_istream<char>&)}’ 
/usr/include/c++/4.6/istream:126:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__ios_type& (*)(std::basic_istream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>, std::basic_istream<_CharT, _Traits>::__ios_type = std::basic_ios<char>] 
/usr/include/c++/4.6/istream:126:7: note: no known conversion for argument 1 from ‘int*’ to ‘std::basic_istream<char>::__ios_type& (*)(std::basic_istream<char>::__ios_type&) {aka std::basic_ios<char>& (*)(std::basic_ios<char>&)}’ 
/usr/include/c++/4.6/istream:133:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:133:7: note: no known conversion for argument 1 from ‘int*’ to ‘std::ios_base& (*)(std::ios_base&)’ 
/usr/include/c++/4.6/istream:169:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:169:7: note: no known conversion for argument 1 from ‘int*’ to ‘bool&’ 
/usr/include/c++/4.6/istream:173:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char, _Traits = std::char_traits<char>] 
/usr/include/c++/4.6/istream:173:7: note: no known conversion for argument 1 from ‘int*’ to ‘short int&’ 
/usr/include/c++/4.6/istream:176:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:176:7: note: no known conversion for argument 1 from ‘int*’ to ‘short unsigned int&’ 
/usr/include/c++/4.6/istream:180:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char, _Traits = std::char_traits<char>] 
/usr/include/c++/4.6/istream:180:7: note: no known conversion for argument 1 from ‘int*’ to ‘int&’ 
/usr/include/c++/4.6/istream:183:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:183:7: note: no known conversion for argument 1 from ‘int*’ to ‘unsigned int&’ 
/usr/include/c++/4.6/istream:187:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:187:7: note: no known conversion for argument 1 from ‘int*’ to ‘long int&’ 
/usr/include/c++/4.6/istream:191:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:191:7: note: no known conversion for argument 1 from ‘int*’ to ‘long unsigned int&’ 
/usr/include/c++/4.6/istream:196:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:196:7: note: no known conversion for argument 1 from ‘int*’ to ‘long long int&’ 
/usr/include/c++/4.6/istream:200:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:200:7: note: no known conversion for argument 1 from ‘int*’ to ‘long long unsigned int&’ 
/usr/include/c++/4.6/istream:205:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:205:7: note: no known conversion for argument 1 from ‘int*’ to ‘float&’ 
/usr/include/c++/4.6/istream:209:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:209:7: note: no known conversion for argument 1 from ‘int*’ to ‘double&’ 
/usr/include/c++/4.6/istream:213:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:213:7: note: no known conversion for argument 1 from ‘int*’ to ‘long double&’ 
/usr/include/c++/4.6/istream:217:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] 
/usr/include/c++/4.6/istream:217:7: note: no known conversion for argument 1 from ‘int*’ to ‘void*&’ 
/usr/include/c++/4.6/istream:241:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>] 
/usr/include/c++/4.6/istream:241:7: note: no known conversion for argument 1 from ‘int*’ to ‘std::basic_istream<char>::__streambuf_type* {aka std::basic_streambuf<char>*}’ 
/usr/include/c++/4.6/bits/basic_string.tcc:998:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&) 
/usr/include/c++/4.6/bits/istream.tcc:957:5: note: template<class _CharT2, class _Traits2> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT2*) 
/usr/include/c++/4.6/bits/istream.tcc:925:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT&) 
/usr/include/c++/4.6/istream:709:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char&) 
/usr/include/c++/4.6/istream:714:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char&) 
/usr/include/c++/4.6/istream:756:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char*) 
/usr/include/c++/4.6/istream:761:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char*) 
[email protected]:~/Desktop$ 
+3

定义' “不起作用”' – 2013-03-18 09:52:56

+0

这是否编译**错误**帮助都:“无效的操作数为二进制表达式( '的std :: stringstream的'(又名“basic_stringstream ')和' int \ *')“换句话说,没有重载的提取操作符需要lhs-istream和rhs-intptr。只是很高兴你没有通过char *,否则你会用segfaults而不是编译器错误。 – WhozCraig 2013-03-18 09:56:09

+1

你为什么期望它工作?您正试图将“std :: stringstream”的内容流式传输到指针中。 – juanchopanza 2013-03-18 09:56:47

回答

1

的问题是,任何类型的指针可以是隐式转换为void*,但void*可以被转换为任何类型的指针。在你的情况下,你应该专注于所有指针的FromString函数。像这样

template <typename T> 
T FromString (const std::string &Text, 
    std::enable_if< ! std::is_pointer<T>::value >::type * = nullptr) 
{ 
    std::stringstream ss(Text); 
    T result; 
    ss >> result; 
    return result; 
} 

template <typename T> 
T FromString (const std::string &Text, 
    std::enable_if< std::is_pointer<T>::value >::type * = nullptr) 
{ 
    std::stringstream ss(Text); 
    void * result; 
    ss >> result; 
    return (T)result; 
} 
+0

我不知道stringstream >> void *被允许。谢谢。 – 2013-03-18 10:26:22

4

你的问题可能实际上缩小到这个简单的测试案例:

std::stringstream ss("0xbf845748"); 
int* p2; 
ss >> p2; 

哪个不行,因为没有这样的超载>>运算符将初始化您的指针。为了完成指针工作的提取,你可以使用void*,或者你甚至可以提取整数,这个数字足够大以保存这个地址,然后使用reinterpret_cast<T>来使你的指针指向这个地址,只是非常小心,不要结束与char*超载,因为这可能会导致你现在正在处理的更严重的问题。

请注意,试图通过使用存储在std::string中的地址来初始化指针实在是个坏主意。在你决定使它工作之前,确保它真的是你想要的。如何避免这种情况最有可能更合理。

+1

即使这样做,OP仍然支持输出流上指针的写入格式。即使开启了十六进制,写入格式也不能保证一致的读取格式与'uintptr_t'类似。此外,整个事情在原始指针写入时没有'void *'-cast,因为*有* char *定义的写入器。即如果'char *'曾经是模板类型,那么OP有一组全新的问题值得担心。 – WhozCraig 2013-03-18 10:05:49

+0

@WhozCraig:确实。通过使用存储在'std :: string'中的地址初始化一个指针似乎根本不是正确的。 – LihO 2013-03-18 10:09:57

+1

是的,这是一个可怕的想法。如果他真的希望它能够工作(这是一个真正的延伸),他可以投到(uintptr_t),然后*执行写操作,而读操作则相反。但随后会弹出一个SFINAE问题,可能需要一个特殊版本的'std :: is_pointer '。总而言之,只是一个彻头彻尾的坏主意,我同意。 – WhozCraig 2013-03-18 10:12:34

2

@LihO,谢谢!这样可行。我不得不在提取指针时使用std :: hex。

string s1 = "0x7fff3e8aee1c"; 
    stringstream ss; 
    ss<<s1; 
    long long unsigned int i; 
    ss>>std::hex>>i; 
    int * i_ptr=reinterpret_cast<int *>(i); 
+1

你应该使用[uintptr_t](http://stackoverflow.com/questions/1845482/what-is-uintptr-t-data-type)。 – 2013-03-18 10:23:14