convert is this right or wrong way

is this the right way or wrong way to convert?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <sstream> // std::stringstream
#include <string>  // std::string
#include <cstring> // strcpy

using namespace std;

template<class T>
void Swap( T& a , T& b )
{ T c = a ; a = b ; b = c; }

template< class T , class U >
void atob ( T& a , U& b)
{
	std::stringstream into; 
	into.str() = "";
	into << a;
	into >> b;
}

void itoc( int& x , char* c )
{
	std::stringstream into; 
	into.str() = "";
	into << x;
	into >> c;
}

void ctoi( char* c , int& x  )
{
	std::stringstream into; 
	into.str() = "";
	into << c;
	into >> x;
}

int main()
{
	int x , y;
	x = 7 ; y = 12;
	Swap<int>( x , y );
	cout << x << " " << y << endl;
	
	// char to int
	char nn = '1';
	int  num = 0;
	atob<char,int>( nn , num );
	cout << num << endl;
	
	// int to char
	num = 5;
	atob<int,char>( num , nn );
	cout << nn << endl;
	
	// int to char[]
	char nm[3];
	num = 20;
	itoc( num , nm );
	cout << nm << endl;
	
	// char[] to int
	nm[0] = '1'; nm[1] = '4';
	ctoi( nm , num ); 
	
	// int to string
	string st= "one";
	atob<int,string>( num , st );
	cout << st << endl;
	
	// string to int
	st = "47";
	atob<string,int>( st , num );
	cout << num << endl;
	
	//char to string
	char ch[] = "changeover";
	st = ch;
	cout << st << endl;
	
	//string to char
	st = "char turn";
	char cha[st.size()+1];
	strcpy( cha , st.c_str() );
	cout << cha << endl;
	
	return 0;
}
Last edited on
I'd recommend using boost::lexical_cast from the Boost Conversion library for this.

itoc() is dangerous. You have no idea how many bytes will be written to the char*. Anything that writes to char* should always take a length argument where the caller can tell you the length of the buffer pointed to by the char*. You should then read from the stream into a string and then copy only what you can to the supplied buffer.

In general it is best to completely discourage the use of C strings for this sort of thing.
Last edited on
thinking in change all to one name.
would it be okay to overload itoc an ctoi ?
will this be okay ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void itoc( int& x , char* c )
{
	std::stringstream into; 
	into.str() = "";
	into << x;
	into.width( sizeof(c)-1 );
	into >> c;
}

// does not like a space , read until space is hit
void stoc ( string& s , char* c)
{
	std::stringstream into; 
	into.str() = "";
	into << s;
	into.width( (sizeof(c)-1)*4);
	into >> c;
}	
Last edited on
now it get space .
1
2
3
4
5
6
7
8
9
void stoc ( string& s , char* c)
{
	int l = (sizeof(c)-1);
	std::stringstream into; 
	into.str() = "";
	into << s;
	into.width( l*4);
	into.getline( c , l*4 );
}
sizeof(c) does not mean what you think it means. It returns the size of the pointer type on your system. It will almost always be either 4 (32-bit systems) or 8 (64-bit systems). You cannot infer the size of the char buffer this way or any way. The buffer size must be passed explicitly by the caller.
on 32bit char = 1byte , on 64bit char = 1 byte ? right !
so why won't it work for char* . when i do sizeof(char*) it always give me the right number.
if string size changes then i could
1
2
3
4
5
6
7
8
9
void stoc ( string& s , char* c)
{
	int l = (sizeof(c)-1);
	std::stringstream into; 
	into.str() = "";
	into << s;
	into.width( l*sizeof(s) );
	into.getline( c , l*sizeof(s) );
}


on 32bit int = 4byte , on 64bit int = 8 byte ? right !
If you want the size of a C string, you're going to have to iterate over it until you get to a NULL or if the calling function will have to give you its size.

For example, this is how strlen gets the size of a string (well, it's my [working] version, anyway..):
1
2
3
4
5
6
size_t strlen(const char* s) {
    size_t len = 0;
    while (s++)
        len++;
    return len;
}


Oh, and sizeof(s) won't work either. You want s.len().
Last edited on
Okay PanGalactic i caught your drift.
pointers has it own bytes , not the objects bytes.

1
2
3
4
5
6
7
8
9
10
11
12
void Convert( string& s , char* c , int size )
{
	cout << " sizeof c : " << size << endl;
	std::stringstream into; 
	into.str() = "";
	into << s;
	into.width( size );
	into.getline( c , size );
}

//.... main and more code
Convert( st , r , sizeof(r) );



Last edited on
Anything wrong with this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <sstream> // std::stringstream
#include <string>  // std::string

using namespace std;

// Convert char
template< class T >
void Convert( T& a , char& c)
{
	std::stringstream into; 
	into.str() = "";
	into << a;
	into.width( 1 );
	into >> c;
}
// Convert to char array
template< class T >
void Convert( T& a , char* c , int size)
{
	std::stringstream into; 
	into.str() = "";
	into << a;
	into.width( size );
	into.getline( c , size );
}
// Convert from char array
template< class T >
void Convert( char* c , T& a )
{
	std::stringstream into; 
	into.str() = "";
	into << c;
	into >> a;
}
// Convert basic
template< class T , class U >
void Convert( T& a , U& b)
{
	std::stringstream into; 
	into.str() = "";
	into << a;
	into >> b;
}

int main()
{
	int a;
	char c;
	
	a = 473;
	c = '1';
	
	cout << c << " to a : " << a << " :: " ;
	Convert( a , c);
	cout << c << endl;
	
	char ca[10];
	Convert( a , ca , sizeof(ca) );
	cout << ca << endl;
	
	string s = "String Convert";
	Convert( s , ca , sizeof(ca) );
	cout << ca;
	return 0;
}
Looks fine to me. The only comment I have is that into.str() = ""; just wastes CPU cycles in the context that it is used. I can be removed without affecting the result.
Topic archived. No new replies allowed.