Please help me to figure out why there is a question mark at my string output. I have been working on this simple reverse a string practice. My code can do it correctly. Then I try to store the reversed string into an array and then convert this array to a string. So here is something wired happened. There is always a question mark at the end of that string. Please teach me the reason of it, and how to get rid of this question mark. Here is my code. Thank you so much
#include <string>
using namespace std;
int main()
{
cout<<"Please enter a string."<<endl;
string str;
cin >> str;
int i=0;
int length = str.length();
char arr[length];
//cout<<length;
while (length != 0) {
arr[i] = str.at(length-1);
length--;
cout<<arr[i];
++i;
}
cout<<endl;
string stri(arr);
cout<<endl<<stri<<endl;
cout<<stri[4];
return 0;
}
A string in C (or many other languages) needs to be terminated by a '\0'. After all, you don't know how large the memory your char* points to is. So you need char[length + 1]. Also, variable-length arrays aren't part of C++. You need to use new[]/delete[] or malloc()/free():
char * arr = new char[length + 1]; // enough space for string + '\0'
char[length] = '\0'; // terminate the string with '\0'
while (length != 0) {
// ... // reverse
}
cout << endl;
string stri(arr); // create the new string
delete[] arr; // don't forget to deallocate the memory
However, if you're dropping down to manual memory allocation, you're usually missing something from the standard library. And indeed, you could simply use the right constructor (it's (4), simplified below):
template <class InputIt>
string::string(InputIt first, InputIt last);
And luckily, std::string provides input iterators that traverse the string backwards via std::string::rbegin() and std::string::rend(). Now your code gets a lot easier:
#include <iostream>
#include <string>
int main()
{
std::cout << "Please enter a string." << std::endl;
std::string str;
std::cin >> str;
std::cout << std::endl;
// Create the new reversed string directly:
std::string reversed_string(str.rbegin(), str.rend());
std::cout << reversed_string << std::endl;
return 0;
}
char arr[length];
should be
char arr[length + 1];
EDIT: or rather (as Jonathan Potter points out, since length is not a compile time constant, your code likely only compiles because this is permitted by your specific compiler, e.g. GNU C++):
char *arr = new char[length + 1];
(and delete [] arr; at some point)
to store the terminating '\0':
arr[length] = '\0';
Related
This question already has answers here:
How do you 'realloc' in C++?
(4 answers)
Closed 9 months ago.
I'm trying to create a program that stores words of a string within the space in an array(For example: If user inputs - "Hello what's up" ,So i want to store Hello, What's,Up in an array of thier respective indices (Hello in 0th index,What's in 1st index and up in 2nd index). I'm using c method of DMA in c++ to achieve this.
Following is my code-
https://code.sololearn.com/cNWxZV9IoG4q/?ref=app
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
int main() {
string sentence;
getline(cin,sentence);
stringstream ss(sentence);
string *words;
int count=0;
while(ss>>sentence)
{
if(count==0)
{
words=
(string*)malloc((count+1)*sizeof(string));
*(words+count)=ss.str();
count++;
continue;
}
words=(string*)realloc(words, (count+1)*sizeof(string));
*(words+count)=ss.str();
free(words);
count++;
}
return 0;
}
But , I'm getting error , Could anyone please fix it?
Don't use C in C++. Just use a std::vector to store the words:
std::string word;
std::vector<std::string> words;
while (ss >> word) {
words.push_back(word);
}
And then you can print the individual words like so:
for (auto& word: words) {
std::cout << word << '\n';
}
Or if you wish to use indices:
for (std::size_t i = 0; i < words.size(); ++i) {
std::cout << i << ": " << words[i] << '\n';
}
The reason why your code fails is, as #heapunderrun mentioned, the fact that std::string has a constructor. If you don't call the constructor in some way, then the string will be in an indeterminate state. When you try to assign to such a string, like in:
*(words+count)=ss.str();
Then your program will crash. If you really want to use manual memory allocation, then you have to use new and delete. You can use malloc() if you really want to, but then you still should use placement new to ensure the std::string objects are correctly constructed inside the memory you allocated. Finally, you probably can't use realloc() safely, you would have to malloc() a new array, copy everything properly to the new array, then free() the old array.
I created a program that the user enters a string. But i need to count how many letters are in the string. The problem is im not allowed to use the strlen()function. So i found some methods but they use pointers but im not allowed to use that yet as we havent learned it. Whats the best way to do this in a simple method? I also tried chars but i dont have luck with that either.
#include <iostream>
using namespace std;
string long;
string short;
int main()
{
cout << "Enter long string";
cin >> long;
cout << "Enter short string";
cin >> short;
return 0;
}
I need to get the length of long and short and print it.
I am trying to use it without doing strlen as asked in some previous questions.
Do you mean something like this?
//random string given
int length = 1;
while(some_string[length - 1] != '\0')
length++;
Or if you don't want to count the \0 character:
int length = 0;
while(some_string[length] != '\0')
length++;
You can count from the beginning and see until you reach the end character \0.
std::string foo = "hello";
int length = 0;
while (foo[++length] != '\0');
std::cout << length;
If you use standard cpp string object I think the best way to get length of your string is to use method:
long.size();
It gives you number of characters in string without end string character '\0'. To use it you must include string library :
#include <string>
If you decide to use char table you can try method from cin:
char long_[20];
cout << "Enter long string\n";
int l = cin.getline(long_,20).gcount();
cout << l << endl;
gcount()
I'm trying to remove all punctuation characters from a std::string in C++. My current code:
string str_in;
string::size_type i, j;
cout << "please input string with punctuation character..." << endl;
cin >> str_in;
for (i = 0, j = 0; i != str_in.size(); ++i)
if (!ispunct(str_in[i]))
str_in[j++] = str_in[i];
str_in[j] = '\0';
cout << str_in << endl;
Is str_in[j] = '\0'; wrong?
If you want to truncate str_in to the first j characters, you can say str_in.resize(j).
If you want to use the standard library you could apply the erase-remove idiom like this:
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string str_in;
std::getline(std::cin, str_in);
// Here is where the magic happens...
str_in.erase(std::remove_if(str_in.begin(), str_in.end(), ::ispunct), str_in.end());
std::cout << str_in << '\n';
return 0;
}
the C++ string type is NOT implemented to be null terminated (although a c_str() call will give you a null terminated string.)
So yes, str_in[j] = '\0' is wrong for at least two reasons:
The str_in.length() will not reflect the size of the string you expect with the punctuation removed.
The null charatcter is an extra charter which will be sent to any output stream,such as cout << str_in;
Using the std::string class you should probably not oveeride the same buffer, but probably use a str_out buffer instead which will have the right length after you copy all the wanted (i.e. excluding the punctuation character), OR you should instead adjust the length of the str_in instead of adding the null.
I think str_in[j] = '\0' is wrong when the string has no any punctuation.
Instead of modifying the same string, create a new string (e.g. str_out) and append to that:
str_out += str_in[i];
I am writing a simple console application to read 3 words and keep them in an array. But after taking three inputs from the console it only displays the third word three times in the console. For example, if I give the input: "one", "two" "three" the output shows only "three" 3 times).
Here is my code:
int main(int argc, char *argv[])
{
char* input[30];
char word[30];
int i=0;
for(i=0; i<3 ;++i)
{
cin >> word;
input[i] = word;
}
input[i] = 0;
i=0;
while(input[i])
{
cout << input[i] << endl;
i++;
}
return 0;
}
What I am doing wrong here? Thanks for any help.
You only have one buffer ( char word[30] ), which you are overwriting each time.
When you do:
input[i] = word;
You're assigning the address of the first element in that one and only buffer to each element in input (arrays degrade to pointers when you use the bare name). You end up with three copies of the same address in input[] (which is address of word, which contains the last thing your read from cin)
One approach to fix this would be to use strdup() and assign the newly allocated string to your input[i]
for(i=0; i<3 ;++i)
{
cin >> word;
input[i] = strdup(word);
}
Also ... if you only are going to have three input "words" you only need an array of 3 char pointers:
char *input[3];
and your output loop would look much like your input loop:
for(i=0; i<3 ;++i)
{
cout << input[i] << endl;
}
Edit: Note that this answer was based on your wanting to use arrays. If this isn't homework that requires that, see bobbymcr's answer - when in C++, use C++.
You marked your question as "C++" (not "C") so I will recommend that you actually use C++ idioms to do this. Modern programs should not be using raw char arrays and pointers except for low level programming and interoperability with legacy or barebones C APIs.
Consider using string and vector as they will make your life much easier. Here is a reimplementation of your program using these types. Aside from the iterator stuff (which I admit is a bit strange until you get used to it), it should seem a lot clearer than the equivalent using char *, etc.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main(int argc, char ** argv)
{
vector<string> input;
for (int i = 0; i < 3; ++i)
{
string word;
cin >> word;
input.push_back(word);
}
for (vector<string>::const_iterator it = input.cbegin(); it != input.cend(); ++it)
{
cout << *it << endl;
}
return 0;
}
The problem is here:
char* input[30];
You maybe tempted to think that this is array of character array, but in essence it's not.
You would either need to dynamically allocate space for the array, or simply use two dimensional character array(fixing the max number of words that you can have).
char input[30][30]; // maximum 30 words having at most 29 characters each
I am trying to convert an integer to char array and I came across this piece of code
int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
But when I try to print the value of s it still prints 5. I don't know if its supposed to do that or am I doing something wrong? Besides I would prefer if I could convert the same int to char array. But I would appreciate any help in the matter.
Thanks!
Code taken from: Alternative to itoa() for converting integer to string C++?
Yes, it's supposed to do that. You'd (primarily) notice the difference from just printing a number out directly if you do some other string-type manipulation on the result (e.g., concatenating it with other strings, searching for characters in the string).
Just for example:
std::cout << i+i; // should print "10"
std::cout << s+s; // should print "55"
Besides I would prefer if I could convert the same int to char array.
char *charPtr = new char[ s.length() + 1 ] ; // s is the string in the snippet posted
strcpy( charPtr, s.c_str() ) ;
// .......
delete[] charPtr ; // Should do this, else memory leak.
If you would like to stop worrying about issues like that you might be interested in boost/lexical_cast.hpp.
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
int main() {
const int i=5;
const char* s = boost::lexical_cast<std::string>(i).c_str();
std::cout << s << std::endl;
}