Why doesn't this loop work like it should?

Basically I know how to put my strings and change them into chars for a program I am writing, but when I try to make a loop that does the same thing, the loop changes the values of each element in the array to the same thing, why???

1
2
3
4
5
6
7
8
9
10
11
12
13
 const char* MAD[10];
	string f;
	for (int x = 0; x < 3; x++) {
		
		cin >> f;
		MAD[x] = f.c_str();
	}
//THIS SHOULD WORK LIKE THIS:
const char* MAD[10]
string f = "hello";
string d = "goodbye";
MAD[0] = f.c_str();
MAD[1] = d.c_str();
please anyone help?
const char* <- this is not a string. This is a pointer.

a std::string contains a buffer which holds the actual string data. When you do MAD[x] = f.c_str(); what you're doing is making MAD[x] point to the data contained in the 'f' string.

When you change 'f' to contain some other data... the data MAD[x] points to changed.

Here's a simpler example of what's going on:

1
2
3
4
5
6
7
8
9
10
int var = 5;  // <- this variable actually contains the 5

int* ptr = &var;  // <- this pointer points to 'var'

cout << *ptr;  // prints 5 as you'd expect

var = 10;

cout << *ptr;  // now this prints 10.  'ptr' still points to 'var'... but 'var' has
  // changed to be 10. 


What you're doing is the same thing:
1
2
3
4
5
6
7
8
9
std::string s = "something"; // <- 's' actually contains the string data

const char* ptr = s.c_str(); // <- 'ptr' DOES NOT contain the string data, it just
   // points to 's's string data

s = "foobar"; // <- s's string data changed

cout << ptr; // <- the data 'ptr' pointed to changed... so this probably won't
   // print "something" any more. 




If you want to convert the string to a series of chars... you will need to allocate an actual buffer to contain the string data (ie: you'll need an ARRAY of chars... not just a pointer).

You can use a function like strcpy to copy the string data over:

1
2
3
4
5
6
7
char buffer[20];  // <- an array of 20 chars
std::string foo = "blarg";

strcpy( buffer, foo.c_str() ); // actually copies the string data into 'buffer'

foo = "woopwooop";
cout << buffer;  // <- prints "blarg" 


please anyone help?


Give us more than 5 mins to respond.
The pointer returned may be invalidated by further calls to other member functions that modify the object.

In your case the string f has reused its internal array and thus you have got the same address every time.

You were just lucky. Don't store pointers to internal arrays that may get deleted on the whim of a string.
can anyone else please help me on this matter? strcpy doesnt not work for const char*, only char*.
closed account (S6k9GNh0)
http://www.cplusplus.com/reference/cstring/strcpy/

Or the more in-depth open-group specification: http://pubs.opengroup.org/onlinepubs/009695399/functions/strcpy.html
I have read both of those but I still don't understand how to make strcpy work when it is a const char* and not a char*. is the only possible solution to convert the const char* to a char* for the time being then to switch it back after?
strcpy doesnt not work for const char*, only char*.


You should not be copying to a const char*. You should be copying to an array of chars. Remember that a const char* is a pointer. Pointers merely contain an address... they do not contain string data.

Therefore you cannot copy string data to a pointer. This is the conceptual problem you seem to be misunderstanding.

You need a buffer (an array) of characters. You then copy the string data to that buffer.

My previous example, reposted:

1
2
3
4
char buffer[20];  // <- an array of 20 chars
std::string foo = "blarg";

strcpy( buffer, foo.c_str() ); // actually copies the string data into 'buffer' 


Again note that 'buffer' is an array and not a pointer. It's also not const because we need to modify it.


That said... you can use a pointer... but only if that pointer points to a buffer.
Last edited on
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
#include <iostream>
#include <string>
#include <memory>
#include <cstring>

// convert string to c-style string, alocate space for 'extra' chars
// release the allocated memoty with delete[]
char* string_to_cstr( const std::string& str, std::size_t extra = 0 )
{
    char* cstr = new char[ str.size() + 1 + extra ] ;

    std::uninitialized_copy( str.begin(), str.end(), cstr ) ; // copy chars
    cstr[ str.size() ] = 0 ; // null terminate

    return cstr ;
}

int main()
{
    std::string abcd = "abcd", efg = "efg" ;

    char* mad[] = { string_to_cstr(abcd,50), string_to_cstr(efg,25),
                     string_to_cstr("ijklmnop"), string_to_cstr("qr",10) } ;

    for( char* cstr : mad ) std::cout << cstr << '\n' ;
    std::cout << '\n' ;

    std::strcpy( mad[0], "bigger string (max 54 chars)" ) ;
    std::strcpy( mad[1], "hello" ) ;
    std::strcpy( mad[2], "world" ) ;
    std::strcpy( mad[3], "bye" ) ;
    for( char* cstr : mad ) std::cout << cstr << '\n' ;

    for( char*& cstr : mad ) { delete[] cstr ; cstr = nullptr ; }
}
abcd
efg
ijklmnop
qr

bigger string (max 24 chars)
hello
world
bye
Last edited on
Do you mean:
1
2
3
4
std::vector<const std::string> MAD;

std::string f;
if ( std::cin >> f ) MAD.push_back( f );
Topic archived. No new replies allowed.