convert const char ** to const char * - c++

I have the following code in which works fine.
const char** array = new const char*[_list.size()];
unsigned index = 0;
for (std::list<std::string>::const_iterator it = _list.begin(); it != _list.end(); ++it) {
array[index] = it->c_str();
index++;
}
My question is, how can I convert const char ** to const char *. Please help.

this is actually an XY question. Hameed should tell what problem he solves, not what step he got to finish to solve problem.What actually the task is? Convert list of strings to array of c strings?
if yes, then should be done somewhat in this way ( sadly, one should copy data)
char** arr = new char*[_list.size()];
int i = 0;
for(auto it = _list.begin(); it != _list.end(); ++it, +i)
{
const char *s = it->c_str(); // should not be modified or deleted
const size_t l = strlen(s);
arr[i] = new char [l+1];
std::copy(&s[0],&s[l], &(arr[i][0]));
}
...
Do you need get i-th element from list?
auto it = _list.begin();
std::advance(it, i);
const char *a = it->c_str();
if doing that in loop for each element, just increment it instead.
concatenate all strings in one? iterate through list, calculate total length, then allocate array of char of that length and copy string one by one. i have vague memory that boost got this as algorithm::join already, but stl require long and frilly code, can't devise that on phone, whoever can edit answer is welcome. in different form that question with dozen solutions presents on stack: How to implode a vector of strings into a string (the elegant way)

Related

Copying a C-style string into memory allocated on free store?

I'm doing an exercise in which I have to copy a c-style string into memory allocated on free store. I am required to do it without using subscripting and relying solely on pointer arithmetic. I wrote the following function-
char* str_dup(const char* s)
{
// count no. of elements
int i = 0;
const char* q = s;
while (*q) { ++i; ++q; }
//create an array +1 for terminating 0
char* scpy = new char[i + 1];
//copy elements to new array
while (*s)
{
*scpy = *s;
++s;
++scpy;
}
*scpy = 0;
return scpy;
}
The function is returning random characters. But if I change it into this-
char* str_dup(const char* s)
{
// count no. of elements
int i = 0;
const char* q = s;
while (*q) { ++i; ++q; }
//create an array +1 for terminating 0
char* scpyx = new char[i + 1];
char* scpy = scpyx;
//copy elements to new array
while (*s)
{
*scpy = *s;
++s;
++scpy;
}
*scpy = 0;
return scpyx;
}
it works. Can someone explain me why first code is not working and second is working?
The first code is not working since you return the final value of scpy, which at that point points at the terminating NUL character, and not the start of the string.
One solution is to do as you did, and save a copy of the original pointer to have something to return.
You should really use strlen() and memcpy(), they make this easier but perhaps they're off-limits to you.

How to use boyer_moore_search to search char * string in memory?

char * pStart = ...;
char * pLast = ...;
std::string pattern("wn3901s");
std::string::const_iterator it = boost::algorithm::boyer_moore_search<>(
???,
???,
pattern.begin(),
pattern.end()
);
I am trying to search a big char* string in memory, pStart points to its first charactor address; pLast points to the last.
However, I don't want to convert the char* string into std::string, because in that case the memory is copied and that is what I want to avoid.
Now I have the problem to pass the first 2 parameters for boyer_moore_search method, which accepts const_iterator there.
Should I add a new inherited class from const_iterator to emulate the char* string?
Could there be any example?
Thank you
You can use char * as iterator
char *iterator_ = boost::algorithm::boyer_moore_search(pStart, pLast, pattern.begin(), pattern.end());
An iterator is any object that, pointing to some element in a range of
elements (such as an array or a container), has the ability to iterate
through the elements of that range using a set of operators (with at
least the increment (++) and dereference (*) operators).
The most obvious form of iterator is a pointer.
http://www.cplusplus.com/reference/iterator/
Exactly, as sliser has just pointed out...
#include<boost/algorithm/searching/boyer_moore.hpp>
#include<cstdio>
#include<cstring>
using boost::algorithm::boyer_moore_search;
int main(int argc, char ** argv) {
const char * text_start = "This is the string in which we will search for the pattern.";
const char * text_end = text_start + strlen(text_start);
const char * pattern_start = "search";
const char * pattern_end = pattern_start + strlen(pattern_start);
const char * found = boyer_moore_search(text_start, text_end, pattern_start, pattern_end);
printf("%s", found);
return 0;
}

C++ - How to append a char to char*?

I've tried so may ways on the Internet to append a character to a char* but none of them seems to work. Here is one of my incomplete solution:
char* appendCharToCharArray(char * array, char a)
{
char* ret = "";
if (array!="")
{
char * ret = new char[strlen(array) + 1 + 1]; // + 1 char + 1 for null;
strcpy(ret,array);
}
else
{
ret = new char[2];
strcpy(ret,array);
}
ret[strlen(array)] = a; // (1)
ret[strlen(array)+1] = '\0';
return ret;
}
This only works when the passed array is "" (blank inside). Otherwise it doesn't help (and got an error at (1)). Could you guys please help me with this ? Thanks so much in advanced !
Remove those char * ret declarations inside if blocks which hide outer ret. Therefor you have memory leak and on the other hand un-allocated memory for ret.
To compare a c-style string you should use strcmp(array,"") not array!="". Your final code should looks like below:
char* appendCharToCharArray(char* array, char a)
{
size_t len = strlen(array);
char* ret = new char[len+2];
strcpy(ret, array);
ret[len] = a;
ret[len+1] = '\0';
return ret;
}
Note that, you must handle the allocated memory of returned ret somewhere by delete[] it.
Why you don't use std::string? it has .append method to append a character at the end of a string:
std::string str;
str.append('x');
// or
str += x;
The function name does not reflect the semantic of the function. In fact you do not append a character. You create a new character array that contains the original array plus the given character. So if you indeed need a function that appends a character to a character array I would write it the following way
bool AppendCharToCharArray( char *array, size_t n, char c )
{
size_t sz = std::strlen( array );
if ( sz + 1 < n )
{
array[sz] = c;
array[sz + 1] = '\0';
}
return ( sz + 1 < n );
}
If you need a function that will contain a copy of the original array plus the given character then it could look the following way
char * CharArrayPlusChar( const char *array, char c )
{
size_t sz = std::strlen( array );
char *s = new char[sz + 2];
std::strcpy( s, array );
s[sz] = c;
s[sz + 1] = '\0';
return ( s );
}
The specific problem is that you're declaring a new variable instead of assigning to an existing one:
char * ret = new char[strlen(array) + 1 + 1];
^^^^^^ Remove this
and trying to compare string values by comparing pointers:
if (array!="") // Wrong - compares pointer with address of string literal
if (array[0] == 0) // Better - checks for empty string
although there's no need to make that comparison at all; the first branch will do the right thing whether or not the string is empty.
The more general problem is that you're messing around with nasty, error-prone C-style string manipulation in C++. Use std::string and it will manage all the memory allocation for you:
std::string appendCharToString(std::string const & s, char a) {
return s + a;
}
char ch = 't';
char chArray[2];
sprintf(chArray, "%c", ch);
char chOutput[10]="tes";
strcat(chOutput, chArray);
cout<<chOutput;
OUTPUT:
test

Using pointers to subsitute characters in C strings

This is not homework, but study for a midterm.
I cannot use any type of array indexing such as str[i] or *(str+i)
I have to take the c-string "EECS280ISAWESOME" and substitute the 'E' with the c-string "XY". I also have to allow for multiple length of the "XY" variable.
The following main is given:
int main () {
const char* S = "EECS280ISAWESOME";
const char* P = "XY";
char result[256];
subsituteChar(S,P,'E', result);
cout << result << endl;
}
My solution seems complex/bad practice/and ugly. I could do it better with the use of deferencing and adding *(R+1) but I dont think it's allowed.
void subsituteChar(const char* S, const char* P, char c, char* R) {
while(*S != '\0') {
if(*S == c) {
const char* PP = P;
while (*P != '\0') {
*R = *P;
R++;
P++;
}
P = PP;
} else {
*R = *S;
R++;
}
S++;
}
}
This works but I am left with XYXYCS280ISAWXYSOMXY2. I have no idea where the weird 2 has came from.
Since this is a study problem, here's a hint to get you started. Try initializing your result array. I did this:
char result[256];
for (int i = 0; i < 250; ++i)
result[i] = 'a';
result[250] = 0;
Now run your code again, and you'll see that you've got lots of 'a' characters at the end of your output, up to the point where you get to character 250. That is, you'll see:
"XYXYCS280ISAWXYSOMXYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
If you want to figure out the rest for yourself, STOP READING NOW.
The problem is that you're not explicitly null terminating your string.
Note that it's not a problem with your last character of S being replaced, but rather with your while loop's terminal condition. Since you aren't manually copying over the '\0' character from S, you're left hoping that the result array is full of '\0' characters, which C and C++ don't guarantee.
Simply adding the following line to the end of your substituteChar function will solve the problem:
*R = '\0';
Does this fit?
#include<stdio.h>
int main () {
const char* S = "EECS280ISAWESOME";
const char* P = "XY";
char result[256];
while(*S)
{
if(*S=='E')
printf("XY");
else
printf("%c", *S);
S++;
}
}
Your code is perfectly correct along with small error. There is a fact of string , everry
string should be terminate with null character. so just add the *R ='\0'; at the end of
while function and this algorithm works perfectely.

Add 2 chars without using strncpy?

How would I manually concatenate two char arrays without using the strncpy function?
Can I just say char1 + char2?
Or would I have to write a for loop to get individual elements and add them like this:
addchar[0] = char1[0];
addchar[1] = char1[1];
etc
etc
addchar[n] = char2[0];
addchar[n+1] = char2[1];
etc
etc
To clarify, if
char1 = "happy"
char2 = "birthday"
I want addchar to = happybirthday
For a C-only solution use strncat:
char destination[80] = "";
char string1[] = "Hello";
char string2[] = " World!";
/* Copy string1 to destination */
strncat(destination, string1, sizeof(destination));
/* Append string2 to destination */
strncat(destination, string2, sizeof(destination) - sizeof(string1));
Note that the strn* family of string functions are safer than the ones without n, because they avoid the possibility of buffer overruns.
For a C++ solution, simply use std::string and operator+ or operator+=:
std::string destination("Hello ");
destination += "World";
destination += '!';
If you consider two trivial loops to be "manual", then yes, without using the standard library this is the only way.
char *append(const char *a, const char *b) {
int i = 0;
size_t na = strlen(a);
size_t nb = strlen(b);
char *r = (char*)calloc(na + nb + 1, 1);
for (i = 0; i < na; i++) {
r[i] = a[i];
}
for (i = 0; i < nb; i++) {
r[na + i] = b[i];
}
return r;
}
Remember to call free.
If you're using c++ just use an std::string. With std::strings, the + operator is supported, so you can do string1+string2.
Without using library functions, here is the procedure:
1. Point to the first character in string1.
2. While the current character at the pointer is not null, increment the pointer.
3. Create a "source" pointer pointing to string2.
4. While the character at the "source" location is not null:
4.1. Copy the character from the "source" location to the location pointed to by the String1 pointer.
4.2. Increment both pointers.
Unless this is homework, use C++ std::string for your text.
If you must use C style strings, use the library functions.
Library functions are optimized and validated, reducing your development time.
Alright, you want something like this:
char1 + char2
First, let's see the insane solution:
C:
char* StringAdd(char* a_Left, char* a_Right)
{
unsigned int length_left = strlen(a_Left);
unsigned int length_right = strlen(a_Right);
unsigned int length = length_left + length_right;
char* result = (char*)malloc(length);
// clear the string
memset(result, 0, length);
// copy the left part to the final string
memcpy(result, a_Left, length_left);
// append the right part the to the final string
memcpy(&result[length_left], a_Right, length_right);
// make sure the string actually ends
result[length] = 0;
return result;
}
C++:
char* StringAdd(char* a_Left, char* a_Right)
{
unsigned int length_left = strlen(a_Left);
unsigned int length_right = strlen(a_Right);
unsigned int length = length_left + length_right;
char* result = new char[length];
// clear the string
memset(result, 0, length);
// copy the left part to the final string
memcpy(result, a_Left, length_left);
// append the right part the to the final string
memcpy(&result[length_left], a_Right, length_right);
// make sure the string actually ends
result[length] = 0;
return result;
}
Now, let's see the sane solution:
char* StringAdd(char* a_Left, char* a_Right)
{
unsigned int length = strlen(a_Left) + strlen(a_Right);
char* result = new char[length];
strcpy(result, a_Left);
strcat(result, a_Right);
return result;
}
So, was this homework? I don't really care.
If it was, ask yourself: what did you learn?