Convert string to constant char - c++

I am trying to convert my string into a const char that can be used with the strtok function. What am I doing wrong?
int _tmain(int argc, _TCHAR* argv[])
{
char * pointer_char;
int pos = 0;
std::string str = " Hello good sirtttttt..!.";
int i = 0;
int length = str.length();
const char * cstr = str.c_str();
cout << "Testing string is " << str << endl << endl;
pointer_char = strtok (str.c_str()," ,.;-!?##$%^&");
}

Do not use .c_str() result with strtok directly.
strtok needs char* not a constant and it tries to change the passed string. Since your passed string comes from a const char* then it's not possible to change it. If you try to cast it to a non-const type before passing it to this function then undefined behavior will be invoked.
You need to make a copy and then pass that copy to strtok, for example:
char *c = strdup(str.c_str()); // It's not standard but simple to write
pointer_char = strtok(c," ,.;-!?##$%^&");
free(c);
Try not to use strtok specially in C++ (you have many alternatives), it is not thread safe.

strtok doesn't take const char * as first parameter it takes a char*. The string has to be modifiable.
char *strtok (char *str, const char *delimiters);
str
C string to truncate.
Notice that this string is modified by being broken into smaller strings (tokens).
Alternativelly, a null pointer may be specified, in which case the function continues scanning where a previous successful call to the function ended.

Related

C++ Copying text from. text from char* var to char* var2

I just started learning c++, andI have problems with uderstanding working on adresses and rewriting variables from one adress to another.
I have a program to correct:
using namespace std;
void cp(char* str2, char* str1) {
cout << &(str1+1);
}
int main()
{
char *str1 = "ppC";
char str2[10] = "Witaj";
// cout << str2 << endl; // Witaj
cp(str2,str1);
}
Problem:
I have to write a function to rewrite text from str1 to str2.I also have to use specified amount of memory to store the text in str2.
But I've got stucked at first step:
I would like to begin with taking the adress of str1 (its adress of str1[0] am i right?) then i would like to go in loop fro after adding +1 to each adress to go through all elements of str1 and write it to new char* var and return it.
As I have understood you are going to write a function that copies a string stored in one character array in another character array.
Usuaaly such string functions also returns pointer to the first character of the destination array.
So instead of
void cp(char* str2, char* str1);
It is better to declare the function like
char * cp( char *str2, const char *str1 );
It is a low level function and t should not check whether there is enough space in the destination array. It is a problem of the caller.
So the function can be defined like
char * cp( char *str2, const char *str1 )
{
char *p = str2;
while ( *str2++ = *str1++ );
return p;
}
Take into account that the second parameter has type const char *. In this case you can use constant arrays as an argument for this parameter including string literals.
Using the variable declarations in your program you could call the function the following way
std::cout << cp( str2, str1 ) << std::endl;

How to manipulate character string being pointed to

I'm sure this is an easy question for most but I'm having trouble trying to figure out why I can't manipulate this sting and better yet how I should go about doing it. So for example we have:
char *str1="Hello World";
All I want to do is manipulate the string that is being pointed to by 'str1'. For example, as shown below, I could output the string and see the original. Then I could add a null character in there and shorten it.
cout << str1 << '\n';
str1[5] = '\0';
cout << str1;
I've also tried:
cout << str1 << '\n';
*(str1+4) = '\0';
cout << str1;
Either way I'm hoping to see something like this:
Hello World
Hello
The error I'm getting in both cases is when I try to alter the string. I know it would be easier to just declare str1 as an array (char str1[] = ....) but I'm given the constraint of having to use the dreaded char *
String literals are stored in read-only memory. You cannot modify them. In fact, in modern C++, attempting to initialise str1 the way you did will give an error. It should be a const char*:
const char* str1 = "Hello World";
This makes it clear that you shouldn't be modifying the chars.
If you want a copy of the string that you can manipulate, you should make str1 an array:
char str1[] = "Hello World";
When you initialise an array with a string literal, the characters are copied into the array.
So after all of the help I've received from you all I went with first determining the length of the strings, initializing an array of the same size+1, and then iterating through the original to save it into an array. Then I was able to manipulate it as i pleased.
int someFunc(char *inpStr){
int counter = 0;
//Find the length of the input string
while(inpStr[counter]!='\0'){counter++;}
//Input initialize an array of same size
char strArray[counter+1];
//Copy whats in the char * to the array and make sure it ends with null
for(int i=0;i<=counter;i++){strArray[i]=*(inpStr+i);}
strArray[counter]='\0';
.....
return 0;
}
Thanks for all the help!
Why you cannot change the str1 has been explained aptly by Joseph. But still if you want to modify it you can use something like this:
char *str = "hello";
char *ptr = new char[strlen(str)+1];
strcpy(ptr,str);
ptr[2] = 'd';
str = ptr;
I hope this solves your problem.

I get a conversion error from char* to char when I try and compile my code

I've cut out a lot of the code to make it easier to read. Specifically I'm trying to rewrite strcat
#include <iostream>
using namespace std;
char MYstrcat(char string1[],char string2[]);
int main()
{
char letter, letter_ans, again;
const int SIZE = 80;
char string1 [SIZE];
char string2 [SIZE];
getting input for the character arrays
cout << "Enter the first string: ";
cin >> string1;
cout << "Enter the second string: ";
cin >> string2;
letter_ans=MYstrcat(string1, string2);
cout << letter_ans;
cin.get(); cin.get();
return 0;
}
this is my version of the strcat function
char MYstrcat(char string1[],char string2[])
{
int i = 0; //Counters
int j = 0;
//Read until null character is encountered then append.
while (string1[i] != '\0')
{
i++;
}
while (string2[j]!= '\0'){
string1[i] = string2[j];
i++;
j++;
}
string1[i]='\0'; // Place a null character in string2.
i get the error in this next line: invalid conversion from 'char*' to 'char'
return string1;
}
char MYstrcat(char string1[],char string2[]); // returns a single character
char *MYstrcat(char string1[],char string2[]); // returns a pointer to a string that can be used like string1[] and string2[]
Likewise,
char letter_ans; // this gives space for a single char, like int int_ans;
char *letter_ans; // this makes a pointer to an array of char's, the proper return type
However, since you are returning string1, it may be possible that you don't even want to use a return type. If you declare your function as so:
void MYstrcat(char *string1,char *string2);
It will operate directly on string1, leaving no need to return a pointer to it.
Arrays decompose in to pointers in C++, so when you do return String1 you are returning a char*, hence the return type of your function should be char*.
You're returning a char in your header, not a string.
The function header char MYstrcat(char string1[],char string2[]);
declares the return type as char, but the function body is returning a string. return string1;
because string1 is an char array. ie:char[]... but your function's return type is char . so you got an error.you can change you function's return type to char*, then test your code. good luck.

Cutting off the end of a char *

So i have a char *. And i want to cut off some bit at the end. So
char *sentence = "My name is Ted";
How do I cut off the Ted. I could make it a string and then use substring (coming from Java thats my go to method) but id rather not do that way. But im not sure how to do it with a char *.
EDIT: Further on the problem. The issue is in a function that takes a process and is meant to return the location when that process is started from. Thats fine i can get that. But the parameter char *procLocation is passed by reference so the location will be sent back there.
I can only get the location that includes the name of the process. I want to cut off the name of the process and just return the location. Ive tried making the location a string and doing a substring (string - length of the processName). Thats fine. But
procLocation = location.c_str(); // where location.substr is the location - the process name
gives back an error: error C2440: '=' : cannot convert from 'const char *' to 'char *'
Since that is a string literal, you can't modify it.
If you did:
char sentence[] = "My name is Ted";
You could simply set the character before Ted to \0.
You might be better off using std::string though.
Instead of cutting off your literal, you could use std::string constructor that copies fewer characters than is available in your char*:
const char *data = "Hello, Ted!";
string s(data, data+8);
cout << s << endl;
This prints Hello, T
This approach is less wasteful than making a std::string and taking a substring.
To your original problem, as you're coming from Java, you should (should, in the sense of RFC2119) definitely use std::string:
#include <string>
#include <iostream>
using namespace std;
int main(int argc, const char** argv) {
// copy c-string to std::string
string arg0 = argv[0];
cout << arg0 << endl;
// find last occurrence of path separator
size_t found = arg0.find_last_of("/\\");
// split off filename part of string
cout << arg0.substr(0,found) << endl;
return 0;
}
Further, you should not (should not, in the sense of RFC2119) declare the char array as a char pointer, but as a char array:
char[] s0 = "Hello World!"; // <-- is better
char * s1 = "Hello World!"; // <-- avoid this
See this post for actual reasons why this is better. It also gives the reasons for why not to modify such rvalue strings.
You've tagged the question 'c++' and 'string' but you say you don't want to do this with string and substr ? Not sure why that is. You should prefer these over char* and C style string manipulation functions wherever possible.
To do it the C++ way:
string sentence = "My name is Ted";
cout << "\"" << sentence.substr(0, sentence.rfind(' ') ) << "\"" << endl;
Although you could (modifying your code slightly so that you have a mutable string) do this in C:
char sentence[] = "My name is Ted";
*strrchr(sentence, ' ') = '\0';
printf("\"%s\"\n", sentence);

How concatenate a string and a const char?

I need to put "hello world" in c.
How can I do this ?
string a = "hello ";
const char *b = "world";
const char *C;
string a = "hello ";
const char *b = "world";
a += b;
const char *C = a.c_str();
or without modifying a:
string a = "hello ";
const char *b = "world";
string c = a + b;
const char *C = c.c_str();
Little edit, to match amount of information given by 111111.
When you already have strings (or const char *s, but I recommend casting the latter to the former), you can just "sum" them up to form longer string. But, if you want to append something more than just string you already have, you can use stringstream and it's operator<<, which works exactly as cout's one, but doesn't print the text to standard output (i.e. console), but to it's internal buffer and you can use it's .str() method to get std::string from it.
std::string::c_str() function returns pointer to const char buffer (i.e. const char *) of string contained within it, that is null-terminated. You can then use it as any other const char * variable.
if you just need to concatenate then use the operator + and operator += functions
#include <string>
///...
std::string str="foo";
std::string str2=str+" bar";
str+="bar";
However if you have a lot of conacatenation to do then you can use a string stream
#include <sstream>
//...
std::string str1="hello";
std::stringstream ss;
ss << str1 << "foo" << ' ' << "bar" << 1234;
std::string str=ss.str();
EDIT: you can then pass the string to a C function taking a const char * with c_str().
my_c_func(str1.c_str());
and If the C func takes a non const char * or require ownership you can do the following
char *cp=std::malloc(str1.size()+1);
std::copy(str1.begin(), str2.end(), cp);
cp[str1.size()]='\0';