How to assign a size to a new string? C++ - c++

I am trying to create an array of pointers to strings. I want each of the strings to have only 3 chars. This is the code I have so far:
string **ptr=new string *[100]; // An array of 100 pointers to strings
for (i=0;i<100; i++) // Assigning each pointer with a new string
{
ptr[i]=new string;
(*ptr[i])[3];
}
I am having trouble with the line (*ptr[i])[3]). If I were to create a srting with only 3 chars not via a pointer I would write:
string str[3];
How do I assign 3 chars with the pointer? Thanks!

std::vector<std::string> vec(100, " ");
That does exactly what you are looking for without the need to manage memory yourself.
string str[3];
That does not create a string with 3 characters, but an array of 3 strings.

(*ptr[i])[3]; simply accesses the fourth character in the string, it doesn't resize it. The std::string DOES provide a resize() method though.
As already mentioned, string str[3] creates an array of three strings but I don't think you're trying to talk about that.
As already pointed out, you can use the string ctor that takes a size argument and a fill char, like so:
ptr[i]=new string( 3, ' ' );
And of course you should use vector.

Related

How to code a strcat function that works with two dynamic arrays

As we know, the strcat function concatinates one c-string onto another to make one big c-string containing two others.
My question is how to make a strcat function that works with two dynamically allocated arrays.
The desired strcat function should be able to work for any sized myStr1 and myStr2
//dynamic c-string array 1
char* myStr1 = new char [26];
strcpy(myStr1, "The dog on the farm goes ");
//dynamic c-string array 2
char* myStr2 = new char [6];
strcpy(myStr2, "bark.");
//desired function
strcat(myStr1,myStr2);
cout<<myStr1; //would output 'The dog on the farm goes bark.'
This is as far as I was able to get on my own:
//*& indicates that the dynamic c-string str1 is passed by reference
void strcat(char*& str1, char* str2)
{
int size1 = strlen(str1);
int size2 = strlen(str2);
//unknown code
//str1 = new char [size1+size2]; //Would wipe out str1's original contents
}
Thanks!
You need first to understand better how pointers work. Your code for example:
char* myStr1 = new char [25];
myStr1 = "The dog on the farm goes ";
first allocates 25 characters, then ignores the pointer to that allocated area (the technical term is "leaks it") and sets myStr1 to point to a string literal.
That code should have used strcpy instead to copy from the string literal into the allocated area. Except that the string is 25 characters so you will need to allocate space for at least 26 as one is needed for the ASCII NUL terminator (0x00).
Correct code for that part should have been:
char* myStr1 = new char [26]; // One more than the actual string length
strcpy(myStr1, "The dog on the farm goes ");
To do the concatenation of C strings the algorithm could be:
measure the lengths n1 and n2 of the two strings (with strlen)
allocate n1+n2+1 charaters for the destination buffer (+1 is needed for the C string terminator)
strcpy the first string at the start of the buffer
strcat the second string to the buffer (*)
delete[] the memory for the original string buffers if they are not needed (if this is the right thing to do or not depends on who is the "owner" of the strings... this part is tricky as the C string interface doesn't specify that).
(*) This is not the most efficient way. strcat will go through all the characters of the string to find where it ends, but you already know that the first string length is n1 and the concatenation could be done instead with strcpy too by choosing the correct start as buffer+n1. Even better instead of strcpy you could use memcpy everywhere if you know the count as strcpy will have to check each character for being the NUL terminator. Before getting into this kind of optimization however you should understand clearly how things work... only once the string concatenation code is correct and for you totally obvious you are authorized to even start thinking about optimization.
PS: Once you get all this correct and working and efficient you will appreciate how much of a simplification is to use std::string objects instead, where all this convoluted code becomes just s1+s2.
You allocate memory and make your pointers point to that memory. Then you overwrite the pointers, making them point somewhere else. The assignment of e.g. myStr1 causes the variable to point to the string literal instead of the memory you allocated. You need to copy the strings into the memory you have allocated.
Of course, that copying will lead to another problem, as you seem to forget that C-strings need an extra character for the terminator. So a C-string with 5 characters needs space for six characters.
As for your concatenation function, you need to do copying here too. Allocate enough space for both strings plus a single terminator character. Then copy the first string into the beginning of the new memory, and copy the second string into the end.
Also you need a temporary pointer variable for the memory you allocate, as you otherwise "would wipe out str1's original contents" (not strictly true, you just make str1 point somewhere else, losing the original pointer).

C++ Reading from array of strings

Question:
How do I extract a character from a string that is an array?
Explained:
Normal strings
string example=("Stack Over Flow");
cout<<example[1];
The output will be:
t
What I want is to extract a letter from an array of strings example:
string str[4];
str[0]="1st";
str[1]="2nd";
str[2]="3rd";
str[3]="4th";
cout<<str[2];
will print
3rd
how could i get the "t" from the str[0]?
just by doing as follow:
str[0][2]; // third character of first string
Some more examples:
string str[4];
str[0]="1st";
str[1]="2nd";
str[2]="3rd";
str[3]="4th";
cout<<str[0][2]<<endl; // t
cout<<str[2][1]<<endl; // r
cout<<str[3][2]<<endl; // h
std::string str[4];
str[0]="1st";
str[1]="2nd";
str[2]="3rd";
str[3]="4th";
Here str is an array of std::string objects. As you know you access elements of an array with operator[]. So the first string in the array is accessed with str[0].
std::string offers operator[] as well. With it you can access characters of the string.
So lets take it step by step.
str - array
str[0] - std::string
str[0][0] - first character of the string str[0]
YOu need one more operator[] call. str[2] is using the [] of the array and returns a reference to the array element at index 2. If you want to get the second character of the first array element then you need
str[0][2]
^ ^
string |
character
Class std::string has its own overloaded operator [] that you used in the first your code snippet
string example=("Stack Over Flow");
cout<<example[1];
If you have an array of objects of type std::string then at first you need to access the desired object stored in the array using the built-in subscript operator [] of arrays as for example
string str[4];
cout << str[1];
In this code snippet expression str[1] returns string stored in the second element (with index 1) of the array. Now you can apply the overloaded operator [] of the class std::string as for example
string str[4];
cout << str[1][1];
You get 't' instead of 's' because you are printing it like this cout<<example[1];
you sohuld do it like this:
cout<<example[0][2];

Using strings as arrays in C++

Our instructor told us that a string is the array of characters, and I was wondering whenever we use any array statically, we have to define its size before compiling the pro-gramme in C++ then why don't we do same with the string?
Thanks in advance.
The compiler can choose an array's size automatically to match its initial content, for example:
int a[] = { 3, 5, 2 };
So this is not something that string literals have and other arrays don't.
The string is an object, which is smarter than a character array. A character array is just an allocation in memory, it has no logic associated with it. However the string (because it is an object) is able to manage its own memory and expand as needed.
In C++ you can overload operators. Because the string class has its [ ] operators overloaded you can use the string as an array and access individual characters. However when you use the [ ] operators you are actually invoking a method on the string (namely operator[ ]).
So you can create a string, expand by adding to it, and access individual characters in it:
string str1 = "Hello "; // create a string and assign value
string str2("World"); // use the constructor to assign a value
str1 += str2; // append one string to another
cout << str1[0]; // should print H
But even though the opeartor overloading give it has the same feel as an array, it's actually an object.
if we talk about char* arr = "hello world";
now here "hello world" is given memory through a string object and the object is initialized by the constructor of the String class.
if we say String str = "hello world";
here again constructor of String class is called and it initializes the str object of String to point to the starting address of "hello world" which is stored somewhere in memory.
here we do not have to give the size, instead of that constructor of string class is doing all the trick of allocating dynamic memory and initializing.

How to convert first 15 characters in a char array to std::string in C++?

I know I can convert character arrays to std::string using: string str(array);
But the question is: Could take part of it and convert to string? (for example, first 15 characters)
By the way, my array is defined on the stack.
Thanks.
You use the constructor that takes two iterators (pointers, which arrays decay to, model Random Access Iterators):
std::string str(array, array+15);
This way you can take any part of the array, not just first 15 characters.
In case you have a char array, use the std::string's constructor, which takes 2 iterators:
std::string str(arr, arr + 15);
In case you have an instance of std::string already, use std::string::substr:
std::string str("my long string full of words");
std::cout << "'" << str.substr(0,15) << "'";
outputs: 'my long string '

Parsing a string to a pointer array of chars: char[0] contains the full string and [1] onward contains nothing

I'm trying to parse a simple string to an array of *char and for some reason when I use string.c_str() it puts the entire string into *char[0] and the rest of the array is left blank (I originally thought that chars could only hold one ASCII character but I guess that they act differently as pointers), could anyone have a scan through my function and tell me if there are any obvious mistakes?
static void SetGame()
{
// Variable Initiation
int myRandom = rand() % (numOfWords - 1);
lengthOfString = wordArray[myRandom].length();
// Reinitiate Pointer Arrays
stringArray = new string[lengthOfString];
isDiscoveredArray = new bool[lengthOfString];
// Parse string to the array of characters
*stringArray = wordArray[myRandom].c_str();
// Set each boolean array value to false
for (int i = 0; i < sizeof(isDiscoveredArray); i++)
{
isDiscoveredArray[i] = false;
}
}
Here are my decelerations of the pointers
// Global Variable and pointer Declerations
string *wordArray;
int numOfWords;
string *stringArray;
int lengthOfString;
bool *isDiscoveredArray;
Any ideas? Thanks.
You are mixing types here. First you build an array of strings and store it in a pointer, then you assign to the first element a const char* coming from c_str. The code you currently have would be if your were creating a string for every character in your selected word.
Make your "stringArray" a const char* to fit with the code you already have, but remove the memory allocation.
You've got an array of std::string and when you deference it (i.e. *stringArray) its the same as stringArray[0], so that is why it always going into the first element of your array.
Since you are setting your array have the same number of elements as the string your are copying has characters, you may just want to use a string rather than a string array to copy it into.
If it supposed to be char* (character array) then you will need to explicitly copy the source, which is the result of wordArray[myRandom].c_str(), into your character array rather than using simple assignment.