#include <stdio.h>
#include <string.h>
int main()
{
std::string data;
data = "hello world";
char string1[] = data;
}
If I must use char string1[] and not char *string1, is there a way I can copy content of string data into this char string1[]?
file.cpp: In function ‘int main()’:
file.cpp:13:22: error: initializer fails to determine size of ‘string1’
You can call method c_str on std::string object and copy result to your array.
Since the size of data may be variable, it cannot be copied via initialization of a static array.
One way you can do it is with dynamic allocation (which C++ string handles automatically):
char *string1 = strdup(data.c_str());
// do stuff with string1
free(string1);
If you are familiar with loops, then the easiest way is to copy the contents of string to char array one by one. As you are not going to use char pointer so you have to fix the size of char array, say 20.
int main()
{
string data;
data = "hello world";
int size = data.size(); // size of data
char string1[20]; //you can change the size of char array but it must be greater than size of data string
for (int i = 0; i < size; i++) {
string1[i] = data[i];
}
return 0;
}
Using stack memory (only if you are sure that the data.size() is less than 1000.):
char result[1000];
strcpy(result, data.c_str());
Or using heap memory:
char* result = new char[data.size() + 1];
strcpy(result, data.c_str());
// ...
delete[] result;
Related
So I am doing a question where I have to join two zero terminated strings, the first contains a word, and the second is empty and twice the size of the original array. I was able to get this working using the following code
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char str1[] = "test";
char str2[(sizeof(str1)-1)*2];
char *p;
int count = 0;
for(p = str1; *p != 0; p++) {
str2[count] = *p;
count++;
}
cout << str2;
}
However I have to use a function with the following prototype
char *combine(char *a);
So I tried this
#include <stdio.h>
#include <iostream>
using namespace std;
char *copy_and_reverse(char *a) {
char str2[8];
int count = 0;
char* b = str2;
for(a; *a != 0; a++) {
str2[count] = *a;
count++;
}
return b;
}
int main()
{
char str1[] = "test";
char *a;
a = str1;
char* b = copy_and_reverse(a);
for(b; *b != 0; b++) {
cout << *b;
}
}
But it does not work (it is printing the string but it's printing a few random characters after it), I'm getting so confused with the pointers, can anyone help me out with this?
Edit: here is the question I am trying to answer
Write a function in C++ that takes as a char * style zero terminated string and returns a char* string twice the length of the input. The first half of the returned string should contain a copy of the contents of the original array. The second half of the string should contain the contents of the original string in reverse order.
The function should have the following prototype:
char *copy_and_reverse(char* a);
Note: you should not use any library functions (e.g from string.h).
There are two big problems in your copy_and_reverse code.
After copying the input string, you are not terminating the result. This means str2 is not a valid string. Fix:
str2[count] = '\0'; // after the loop
copy_and_reverse returns a pointer to a local variable (str2). After the function returns, all its local variables are gone, and main is dealing with an invalid pointer. To fix this, either use static memory (e.g. by declaring str2 as static or making it a global variable) or dynamic memory (allocate storage with new[] (or malloc())). Both approaches have their disadvantages.
Minor stuff:
variable; does nothing (see for (a; ...), for (b; ...)).
str2 isn't big enough for the final result. str1 is 5 bytes long ('t', 'e', 's', 't', '\0'), so char str2[8] is sufficient for now, but in the end you want to allocate length * 2 + 1 bytes for your result.
I believe that this will suit your needs:
#include <stdio.h>
#include <stdlib.h>
static char* copy_and_reverse(char* a);
static int strlen(char *c); // self-implemented
int main(void) {
char *a = "some string";
char *b = copy_and_reverse(a);
printf("%s", b);
free(b);
return 0;
}
static char* copy_and_reverse(char* a) {
int n = strlen(a);
char *b = new char[n * 2 + 1]; // get twice the length of a and one more for \0
for (int i = 0; i < n; ++i) { // does copying and reversing
b[i] = a[i];
b[i+n] = a[n-i-1];
}
b[2 * n] = '\0'; // null out last one
return b;
}
static int strlen(char *c) {
char *s = c;
while( *s++ );
return s-c-1;
}
If it makes sense.
This is how it looks so far.
#include <iostream>
int main()
{
char *buffer;
buffer = new char[100];
std::cin >> buffer;
const int size = strlen(buffer);
char input[size];
delete buffer;
return 0;
}
I know I can use the string library but I'm trying to do without it.
I want to make the char size (in the code char input) depending on the input size.
The errors which I am getting is
expression did not evaluate to a constant
expression must have a constant value
on line 12 which is the
char input[size];
I know I can use the string library but I'm trying to do without it.
You can use std::vector<char>. If that is not an option either, allocate memory yourself and make sure that you deallocate the memory.
char* input = new char[size+1]; // Add an extra for the terminating null characterr
....
delete [] input;
For std::cin you need to pre-allocate a buffer. If you plan on using char[] and you really have to avoid strings you have to make sure you allocate enough memory.
Alternatively you can read char by char with scanf("%c",&newChar) until user inputs an escape character and allocate memory for array as you go.
I don't suppose you're limited to using iostream ?
If it is the length of used space in the buffer array you are trying to assign to size for the input array, there are two methods you can use...
#include <iostream>
using namespace std;
int main()
{
char *buffer = new char[100];
cin >> buffer;
int spaceUsed = 0;
for (unsigned int i = 0; i < 100; i++)
{
if (buffer[i] != '\0')
spaceUsed++;
}
char input[spaceUsed];
delete [] buffer;
return 0;
}
OR...
#include <iostream>
using namespace std;
int main()
{
char *buffer = new char[100];
cin >> buffer;
int spaceUsed = 0;
while (*buffer++)
spaceUsed++;
char input[spaceUsed];
delete [] buffer;
return 0;
}
Both code snippets do the exact same thing. Of course, using the string library would make your life much easier though.
I my trying to copy a value into a char.
my char array is
char sms_phone_number[15];
By the way, could tell me if I should write (what the benefic/difference?)
char * sms_phone_number[15]
Below displays a string: "+417611142356"
splitedString[1]
And I want to give that value to sms_from_number
// strcpy(sms_from_number,splitedString[1]); // OP's statement
strcpy(sms_phone_number,splitedString[1]); // edit
I've got an error, I think because splitedString[1] is a String, isn't?
sim908_cooking:835: error: invalid conversion from 'char' to 'char*'
So how can I copy it correctely.
I also tried with sprintf without success.
many thank for your help.
Cheers
I declare spliedString like this
// SlitString
#define NBVALS 9
char *splitedString[NBVALS];
I have that function
splitString("toto,+345,titi",slitedString)
void splitString(char *ligne, char **splitedString)
{
char *p = ligne;
int i = 0;
splitedString[i++] = p;
while (*p) {
if (*p==',') {
*p++ = '\0';
if (i<NBVALS){
splitedString[i++] = p;
}
}
else
{
p++;
}
}
while(i<NBVALS){
splitedString[i++] = p;
}
}
If I do a for with splitedString display, it display this
for(int i=0;i<4;i++){
Serialprint(i);Serial.print(":");Serial.println(splitedString[i]);
}
//0:toto
//1:+4176112233
//2:14/09/19
I also declared and want to copy..
char sms_who[15];
char sms_phone_number[15];
char sms_data[15];
//and I want to copy
strcpy(sms_who,splitedString[0]
strcpy(sms_phone_number,splitedString[1]
strcpy(sms_date,splitedString[2]
I know, I am very confused with char and pointer * :o(
The declaration:
char * SplittedString[15];
Declares an array of pointers to characters, a.k.a. C-style strings.
Given:
const char phone1[] = "(555) 853-1212";
const char phone2[] = "(818) 161-0000";
const char phone3[] = "+01242648883";
You can assign them to your SplittedString array:
SplittedString[0] = phone1;
SplittedString[1] = phone2;
SplittedString[2] = phone3;
To help you a little more, the above assignments should be:
SplittedString[0] = &phone1[0];
SplittedString[1] = &phone2[0];
SplittedString[2] = &phone3[0];
By definition, the SplittedStrings array contains pointers to single characters, so the last set of assignments is the correct version.
If you are allowed, prefer std::string to char *, and std::vector to arrays.
What you need is a vector of strings:
std::vector<std::string> SplittedStrings(15);
Edit 1:
REMINDER: Allocate space for your spliedString.
Your spliedString should either be a pre-allocated array:
char spliedString[256];
or a dynamically allocated string:
char *spliedString = new char [256];
Strings and Chars can be confusing for noobs, especially if you've used other languages that can be more flexible.
char msg[40]; // creates an array 40 long that can contains characters
msg = 'a'; // this gives an error as 'a' is not 40 characters long
(void) strcpy(msg, "a"); // but is fine : "a"
(void) strcat(msg, "b"); // and this : "ab"
(void) sprintf(msg,"%s%c",msg, 'c'); // and this : "abc"
HTH
I need to pass a char pointer to function, then change the value that it points to inside the function and print values outside the function.
The problem I have is that I'm losing it when I leave function and try to print it outside. What can I do to avoid this?
This is an code example:
char array[] = "Bada boom";
char *pText = array;
reverseText(pText);
cout << (pText);
cout should print
moob adaB
When I print inside the function, everything is fine(it prints reversed).
My task is to print It out outside the function (as you can see in a 4th line of code)
This is the full of code which have the bug (printing inside func works, outside didn't work)
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
char reverseText(char *text);
int main(){
char array[] = "Bada boom";
char *pTekst = array;
reverseText(pTekst);
cout << (pTekst); //in here it doesn't work
}
char reverseText(char *text){
char befRev[100]; int lenght=-1;
/*until *text doesn't meet '\0' */
for(int i=0;*text!='\0';i++){
befRev[i]=(*text);
text++;
lenght++;
}
/*reversing*/
int j=0;
for(int i=lenght;i>=0;i--){
*(text+j)=befRev[i];
j++;
}
for(int i=0;i<=lenght;i++) //in here it does print the right value
cout << text[i];
};
Just re-arrange the array in-place. The pointer itself doesn't need to change:
#include <cstring>
#include <algorithm>
void reverseText(char* array)
{
auto len = std::strlen(array);
std::reverse(array, array+len);
}
int main()
{
char array[] = "Bada boom";
char *pText = array;
reverseText(pText);
std::cout << pText << std::endl;
}
Output:
moob adaB
If you really wanted to provide a pointer that points to a different address to the caller, you could simply return it:
char* foo(char* stuff)
{
char* tmp = ....;
...
// do some stuff
...
return tmp;
}
Alternatively, you could pass the pointer by reference, but the intent is less clear than in the previous version:
void foo(char*& stuff)
{
stuff = something_else;
}
But in both cases, you must make absolutely sure the thing the new pointer points to is valid outside of the function. This might require some dynamic memory allocation. For your case, it seems the best and simplest option is to re-arrange the array in place.
To answer your question, you have an error in logic. Notice that in your first loop in reverseText you increment the local pointer text. In your second loop you did not reset text to it's original value so beforeRev is being copied over starting at location text+offset.
If you were to look at pText on return from call to reverseText you would find it contains:
"Bada boom\0moob adaB"
Your reverseText should be renamed palindrome :)
This is pretty straightforward. Some points to note:
An array decays to a pointer when you pass it to a function.
You are passing in a null terminated string. So the length of the char array you are passing in is the length of the string (including white space) +1.
Because you are using a pointer there is no need to assign a temp variable to hold everything.
Here is some code in C that is easy to translate to C++. Working out the actual reverse algorithm is left for you as an exercise.
#include<stdio.h>
void reverseText(char* text)
{
// Hint: It can be done in one loop!
int i;
for(i = 0; i < 9; i++)
{
// Your algorithm to reverse the text. I'm not doing it for you! ;)
*(text + i) = 'r';
}
}
int main()
{
char array[] = "Bada boom";
reverseText(array);
printf("The text reversed: %s\n", array);
return 0;
}
My final code:
#include <iostream>
void reverseText(char* text){
int length=-1; char tmp;
/*Length = sign from 0 to 8 without counting explicit NUL terminator*/
for(int i=0;*(text+i)!='\0';i++){
length++;
}
int j=0; int i=length;
while(j<i){
tmp=*(text+j); //tmp=first
*(text+j)=*(text+i); //first=last
*(text+i)=tmp; //last=tmp
j++;
i--;
}
}
int main(){
char array[] = "Bada boom";
char *pText = array;
reverseText(pText);
std::cout << pText;
}
I should have read more about pointers before I started this exercise.
You can either return a pointer or pass a pointer to pointer as a function argument.
//pointer to pointer
void reverseText(char** textPtr) {
char* newText = ...; //initialize;
...
*textPtr = newText; //assign newText
}
//return pointer
char* reverseText(char* text) {
char* newText = ...; //initialize
return newText;
}
Remember that if you allocate memory in this function you must do it dynamically (with new or malloc) and you have to free it afterwards (with delete or free respectively). Memory allocation in a function like this is probably a bad practice and should be avoided.
I am trying to remove characters from a char pointer and would like to store them back in a new char pointer variable let's say "temp". So I would have something like this:
char *test = "1#2#3$4%5^6&7*8!9#1#0";
char *temp = "";
then remove the "#,#,$,%,^,*,!,#,#," and place the new values of "12345678910" into *temp. This would make temp be equal to "12345678910".
Is this possible?
I have been doing this with string but I really need to do this with the char pointers. Here is how I have done this with string:
std::string str("1#2#3$4%5^6&7*8!9#1#0");
std::string temp("");
char chars[] = "##$%^&*!";
for (unsigned int i = 0; i < strlen(chars); ++i)
{
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
}
temp = str;
So you see here I am doing this all will strings but I just cannot seem to get away with asigning a char * variable like test to a string because its an illegal conversion. However why am I able to set my char * variables equal to string like so?
char *test = "123456789";
However this is illegal?
std::string str("1#2#3$4%5^6&7*8!9#1#0");
char chars[] = "#";
for (unsigned int i = 0; i < strlen(chars); ++i)
{
str.erase (std::remove(str.begin(), str.end(), chars[i]), str.end());
}
char *test = str; //Illegal point
Thank you for your time.
change
char *test = str;
into:
char *test = str.c_str();
c_str is a method that creates c style char array from original string for you.
EDIT: this is a more safe way, a copy of the c string will be obtained:
#include <cstring>
#include <cstdlib>
...
char *test = strdup(str.c_str());
... // process the string
free(test);
Here you have a reference to std string class.
Manpage for strdup.
Anything you can do with iterators you can also do with pointers to an array. Say, an array of chars:
char str[] = "1#2#3$4%5^6&7*8!9#1#0";
char chars[] = "#";
for (unsigned int i = 0; i < strlen(chars); ++i)
{
*std::remove(str, str+strlen(str), chars[i])=0;
}
Notice that I used the fact that std::remove returns an iterator (in this case char*) to the "one after last" element and set that char to 0 - making sure it stays a zero-delimited string