Reputation: 11
I was recently working on a problem teaching new users of C++, which I myself am, how to use cstrings and the different implementations of them compared to the imported string object in C++. As I was working on the problem, I came across an error where, despite initializing the size of the cstring to an appropriate length for the operations that were being done, the cstring was being outputted strangely.
When I would go to print out the cstring using cout, it would print some of the cstring correctly, but oftentimes the first several characters were random characters that had nothing to do with the operations being done to the cstring. However, I found a way to definitively prevent those characters from being printed; however, I am curious as to why this works as well as what the issue is here.
I found that adding cout << "";
on its own line prior to printing the cstring resolved the issue of the random characters being outputted when printing the cstring. However, this seems like only a temporary fix and I am looking to find a more educated approach to solving this issue.
Below I have included the code that was causing the errors.
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
int main() {
vector<string> words = {"Hello,", "and", "welcome", "to", "the", "world", "of", "C++!"};
// Calculate the total number of characters in the words vector
// (including an additional character for space)
int length = 0;
for(int i = 0; i < words.size(); i++) {
length += words.at(i).length() + 1;
}
cout << ""; // Removing this line of code will cause the output to do strange things
// Initialize the cstring to be of size length
char cstring[length];
// Build the cstring using cstring library functions
for(int i = 0; i < words.size(); i++) {
strcat(cstring, (words.at(i) + " ").c_str());
}
// Null-terminate the cstring
cstring[length-1] = '\0';
// Output the cstring
cout << cstring << " " << strlen(cstring) << endl;
return 0;
}
If the line of code containing cout << "";
is removed, the output looks something like this, with a random amount and random set of characters at the beginning of the output each time:
`k+��Hello, and welcome to the world o 39
However, by including the line, I am able to achieve the desired output:
Hello, and welcome to the world of C++! 39
Upvotes: 1
Views: 312
Reputation: 310970
For starters variable length arrays is not a standard C++ feature
// Initialize the cstring to be of size length
char cstring[length];
Secondly you defined an uninitialized array. So using strcat invokes undefined behavior
strcat(cstring, (words.at(i) + " ").c_str());
This statement
// Null-terminate the cstring
cstring[length-1] = '\0';
is redundant because the function strcat
appends also the terminating zero provided that the character array you declared has a space to accommodate the zero character (and you forgot to reserve a space for the terminating zero in the array).
If the compiler supports variable length arrays then the program can look the following way
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
int main()
{
std::vector<std::string> words =
{
"Hello,", "and", "welcome", "to", "the", "world", "of", "C++!"
};
// Calculate the total number of characters in the words vector
// (including an additional character for space)
size_t length = words.size();
for ( const auto &s : words ) length += s.length();
// Initialize the cstring to be of size length
char cstring[length + 1];
cstring[0] = '\0';
// Build the cstring using cstring library functions
for ( const auto &s : words )
{
std::strcat( cstring, ( s + ' ' ).c_str() );
}
// Output the cstring
std:: cout << cstring << ' ' << length << std::endl;
return 0;
}
The program output is
Hello, and welcome to the world of C++! 40
Upvotes: 1