long strings not accepted?

Hi everyone,

This must be pretty basic, but I don't understand it. Consider the following code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main(int argc, char *argv[])
{
    //string str ="CREATE  TABLE Contactos (id INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL , Nombre VARCHAR, Apellidos VARCHAR, email varchar, telefono varchar)";
    string str ="Hola Mundo!";
    char *str_adr ;
    
    //sprintf( str_adr, "%s", str.c_str());
    strcpy( str_adr,str.c_str());
    
    cout << str_adr <<endl;

    system("PAUSE");
    return EXIT_SUCCESS;
}


I am trying to put that SQL command into a char *, but it doesn't happen. You'll notice that variable str has two definitions/assignments. The first is an SQL command (which I intend to use with sqlite, and works on its own). The second is "Hola Mundo!" ("Hello World" in Spanish. I also have a char * str_adr. My goal is to get the SQL command to print out of this pointer, and seen in the cout further below.

Using both strcpy and the commented out sprintf, printing "Hola Mundo!" works. But using either command to try and print out the SQL string causes the program to end prematurely (the system("PAUSE") command is not executed). Why doesn't it accept the larger string? I also included <cstring> and <string>, since I'm not sure which is correct. Any help on this will be greatly appreciated.

Thanks in advance!

Do not multi-post, please.

*str_adr is never initialized. It's declared, but not initialized. You need to do that before copying anything into it. That said, neither the long string nor the shorter string should work.

Also, you were right to include both headers. You need <cstring> for strcpy and <string> for std::string. Why are you mixing them, though? Why are you changing a C++ string to a C string?

-Albatross
Line 12:

 
char *str_adr ;


This creates a 'pointer' to character data in memory. A character array. But it doesn't 'point' anywhere. You defined it but did not give it a value.

So it basically has some random value. It poins to some random memory location.

So when you issue your strcpy(str_adr,str.c_str()); you are copying your string data into some unknown memory location.

What you need to do is allocate some memory from the runtime system and set your pointer pointing to that memory like this:


 
char* str_adr  = new char[str.length() + 1];


Notice how long I made the memory request? I made it one character larger than the string you want to copy into it.

That is because the strcpy command will add a single character with the value of zero '\0' to the end of the data. This is the convention for storing strings in raw memory.
Last edited on
Hi,

Sorry about the multiple posts, I kept getting a "Page not found" message when I clicked submit (guess my connection wasn't that good). I will try as Galik suggests and let you know if it works.

As for mixing C and C++ strings, well, some of sqlite's library functions take char* as arguments (specifically, I am trying to use sqlite3_prepare(), which takes a char* to the SQL command). I don't know how to make multiple character string using char*'s. The tutorial on this site says that I should be able to do something like this:

char * str;
*str ="My String;

But when I try this in my compiler (Bloodshed Dev-Cpp with MinGW), only the first character is passed into the sqlite3_prepare() function. So I figured I should use a std::string, and convert into char *. I'll let you know if it works.
Use .c_str() if you need a char* from an std::string.
This is not quite what you want:

1
2
char * str;
*str ="My String; 


I think you mean this:

1
2
char * str;
str ="My String";


Hi,

I tried it as Galik suggested and it worked! I was able to use this info and successfully call sqlite3_prepare(). Many thanks!

I do have some questions, though. Why doesn't it work to assign a char* like

1
2
char* str;
*str ="My string!"


Does the "value of" operator (*) have a different meaning on that side of an assignment statement?

Also, on this site's pointers tutorial, I notice that pointer values assigned using this scheme. But those examples were using int *. Is it different because int always takes the same amount of memory, whereas a char* may be longer?
String literals are, the last time I checked, pointers themselves, not pure segments of data.

-Albatross
Last edited on
* is the 'indirection operator'.

When you say char* ptr; you are setting aside a piece of memory called 'ptr' in which to store the location of a character.

When I say: char* ptr = "Some text"; I am storing the location of the FIRST character of the string "Some Test" in the memory location called 'ptr'.

So ptr holds the location of the FIRST character of the sequence of characters which make up my string.

If I want to make ptr 'point' to the location of a different string I would say this:

ptr = "New text";

So by modifying ptr alone I modify the particular area of memory that it points to.

So what if I want to modify the string itself? What if I want to change the characters of the string rather than make my ptr point to a different one?

Then I use *

If I want to EXAMINE the actual character that ptr points to I say *ptr. It means "go to the address in memory recorded in the variable ptr and give me the character stored there".

For example:

1
2
3
char* ptr = new char[10]; // give ptr the location of 10 characters 

*ptr = 'M'; // set the first character to the letter M 


If you want to set the second character then you have to add 1 to the value of ptr to move the access to the next memory location up:

 
*(ptr + 1) = 'r'; // set the second character to the letter r 


and

 
*(ptr + 2) = ' '; // set the third character to a space 


and

 
*(ptr + 3) = 'X'; // set the fourth character to the letter X 


By convention when you place a string of characters directly in memory like this you need to make the last character a zero 0.

 
*(ptr + 4) = 0; // set the fifth character 0 to end the string. 


Of course its better to use the ready made function to do all this for you:

1
2
3
char* ptr = new char[10]; // give ptr the location of 10 characters 

strcpy(ptr, "Mr X"); // copy the string "Mr X" into the memory beginning at ptr. 

Topic archived. No new replies allowed.