2013-03-18 149 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