#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
cin>>s1;
int n=s1.size();
string s2;
for(int a=0;a<n;a++)
{
s2[a]=s1[n-1-a];
}
cout<<s2;
}
However I am not getting any output, But I can print elements of reversed string. Can anybody please help.
string s2; // no size allocated
for(int a=0;a<n;a++)
{
s2[a]=s1[n-1-a]; // write to somewhere in s2 that doesn't exist yet
You are writing into elements of s2 that you never created. This is Undefined Behaviour, and anything may happen, including appearing to work normally. In this case, you are probably overwriting some random place in memory. It might crash, or that memory might really exist but not break anything else right away. You might even be able to read that back later, but it would only seem to work by pure accident.
You could catch this problem by always using s2.at(a) to access the data, as it will do a range check for you. ([] does not do a range check). There's a cost to this of course, and sometimes people will skip it in circumstances where they are certain the index cannot be out of bounds. That's debateable. In this case, even though you were probably sure you got the maths right, it still would have helped catch this bug.
You need to either create that space up front, i.e. by creating a string full of the right number of dummy values, or create the space for each element on demand with push_back. I'd probably go with the first option:
string s2(s1.size(), '\0'); // fill with the right number of NULs
for(int a=0;a<n;a++)
{
s2.at(a)=s1.at(n-1-a); // overwrite the NULs
You might want to choose a printable dummy character that doesn't appear in your test data, for example '#', since then it becomes very visible when you print it out if you have failed to correctly overwrite some element. E.g. if you try to reverse "abc" but when you print it out you get "cb#" it would be obvious you have some off-by-one error.
The second option is a bit more expensive since it might have to do several allocations and copies as the string grows, but here's how it would look:
string s2; // no space allocated yet
for(int a=0;a<n;a++)
{
s2.push_back(s1.at(n-1-a)); // create space on demand
I assume you are doing this as a learning exercise, but I would recommend against writing your own reverse, since the language provides it in the library.
You are utilizing something called Undefined Behaviour in your code. You try to access element of s2 at a position, but your string does not have that many chars (it's empty).
You can use std::string::push_back function to add a character on the last postion, so your code would look like this:
for(int a=0;a<n;a++)
{
s2.push_back(s1[n-1-a]);
}
EDIT, to address the other question, your console window probably closes before you can notice. That's why "you don't get any output".
Try this: How to stop C++ console application from exiting immediately?
You can use the inbuilt reverse function in c++
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s1 = "string1";
reverse(s1.begin(),s1.end());
cout << s1;
return 0;
}
Hope that helps :)
You can just construct the string with reverse iterators:
std::string reverse ( std::string const& in )
{
return std::string { in.crbegin(), in.crend() };
}
Related
I am kinda new to programming, so pardon me for any stupid questions :P, i noticed that when i write this
int main()
{
string s;
s[0]='a';
cout<<s.size();
cout<<s<<" ";
cout<<s[0];
return 0;
}
The output is 0 a , firstly why is the size 0? and why didn't anything get printed when i write cout<<s; but it gives a for cout<<s[0]. if i use push_back it gives normal out put.
int main()
{
string s;
s.push_back('a');
cout<<s.size();
cout<<s<<" ";
cout<<s[0];
return 0;
}
output :- 1a a
I might have overlooked something but i would be really appreciate if some could point out the cause.
Thank you.
EDIT: Such fast replies! thanks for your answers, i couldn't figues out how to reply to comments so edited the question body(first time using stackoverflow),
(any help on this would be appreciated as well), one more thing so when i use cout<<s[0] does it give a because a was stored on the next address of string
s?
and once again thanks for clearing that up!
What you've overlooked is that in C++ strings don't automatically grow when you assign characters to them. So
string s;
s[0]='a';
is an error because the s has size zero so there is no 'room' for the character 'a'. The correct way to add a character to a string is to use push_back which is why your second example works.
Because of the error your first example has what's called undefined behaviour (UB for short). This means the output of your program is not predictable at all, and it's more or less a waste of time asking why it outputs what it does. It could just as easily crash.
This:
string s;
creates a string containing no characters. Then this:
s[0]='a';
attempts to make a change to one of those non-existent characters. The result of this is undefined behaviour - your program goes into an unknown state.
If you would like to make your compiler warn you about this problem, you can use the at() member function of string:
s.at(0) = 'a';
Now your program will throw an std::out_of_range exception when you try to change that non-existant character.
Containers don't automatically allocate storage, so you are writing outside the allocated storage. In other words, that's a bug in your program. One advise: Many C++ implementations have a way to activate diagnostics for debugging programs, those would have caught this error.
when I write this
string s;
s[0]='a';
the output is 0, firstly why is the size 0?
The output is zero because operator[i] assumes that the string has sufficient space to store i+1 characters. In your case, string's size is zero, so accessing element at index 0 is undefined behavior.
and why didn't anything get printed when I write to cout
The same thing reason applies: after undefined behavior the program could output anything, but it happens to output nothing.
int main()
{
string s;
s='a';
cout<<s.size();
cout<<s<<" ";
cout<<s[0];
return 0;
}
Just take off [0] after s in initialisation because s is of type string not type char.
Just write s and it will work.
I was trying to write a program to enter texts like passwords (display "*" instead of the character which in input by the user).
The problem is, when I use char arrays to store the password, the program works fine, but when I use a string class variable for the same purpose, my program crashes while displaying the string.
Here is the code:
// *********THIS CODE WORKS FINE***********
#include <iostream>
#include<string>
#include<conio.h>
int main()
{
using namespace std;
int i=0;
cout<<"Enter a password,press ENTER to finish writing"<<endl;
char passw[20];
passw[i]=getch();
while(passw[i]!=13)
{
i++;
cout<<"*";
passw[i]=getch();
}
passw[i+1]='\0';
cout<<"\nPassword is "<<passw;
return 0;
}
Now when I replace char passw[20] with string passw:
//**********THIS CODE CRASHES!!*********
#include <iostream>
#include<string>
#include<conio.h>
int main()
{
using namespace std;
int i=0;
cout<<"Enter a password,press ENTER to finish writing"<<endl;
string passw;
passw=getch();
while(passw[i]!=13)
{
i++;
cout<<"*";
passw[i]=getch();
}
cout<<"\nPassword is "<<passw;
return 0;
}
Can anybody explain why this is happening?
Just started with strings and there's just too much for me to know about strings :)
In string you can use string concatenation.
you can save your char and add it to your string variable.
char ch;
string pass;
ch=getch();
pass=pass+ch;
You're accessing a location (passw[i]) that is not yet existing in your std::string and you're not storing it correctly to a string. You should use the method passwd.push_back(char) to store it.
Check for reference: http://en.cppreference.com/w/cpp/string/basic_string/push_back
A string works differently compared to a char array. You probably know that char passw[20] in your first example creates an array with space for up to 20 chars. These can then be accessed using operator[] without a problem. A string, unlike a basic array, is a dynamic data structure, meaning it grows and shrinks over time as your program runs. Its content can also be accessed using operator[], however, this will not append to the string, it can only be used to change what is already there.
It's important to note that in c++, not all operations will perform what is known as bounds checking. In your second example, you access the i-th character of your string and write a character to that location. However, what would happen if you try to write, for instance, to the 10-th character of a string that only has space for 5? When doing so via operator[], the program will write to whatever location the 10-th character would be at, even though that part of memory is actually not part of the string. Anything could be there and will be overwritten by that operation. As you can probably imagine, this is not desirable at all and can lead to all sorts of problems later down the line. If you're lucky, your program will crash immediately on the write. It did not in your case, however, that's not a good thing; writing out of bounds can cause a heap corruption (the heap being a certain part of memory) which generally leads to a crash at some point down the line.
It's fine to use operator[] to change a strings characters if and only if you know whatever index you're accessing is within the strings size. Otherwise, you need to append to the string using an appropriate member function. These will enlarge the string if necessary.
You always need to pay attention when working with dynamic memory and what parts of it you're accessing (in your first example, for instance, you would also write out of bounds if your password is too long).
Is it possible to fix size of string variable. For example I want string variable str_new of capacity 5. P.S: I don't want to use char str_new[5]. I want to use string class. So the variable declaration should not use keyword char. Is this possible?
EXAMPLE: string str_new;
Is there any way to make sure that str_new size is fixed as 5. This question might be absurd. Please enlighten.
This code throws exception just after execution of one iteration of 'for' loop. There might be better ways to copy one string to another. But I want to copy it as mentioned below. Can someone tell me how to fix the bug, or below code cannot be fixed as its totally messed up?
string str_old = "abcde";
string str_new;
for (int i = 0; i < 5; i++)
{
str_new[i]= str_old[i];
}
However This code works fine if I do following changes
string str_new = " ";
So do I really need to explicitly initialize with blank spaces. Or there can be any other way.
You are asking two questions, and this sound very much like a homework question.
Is it possible to fix size of string variable.
There isn't any reasonable way to fix the size of a string to a size of X, and I can't think of any possible reason why you would even want to try to do so. That said, if there really is some business/homework rule that requires this, then simply check the size of the string before putting anything into it, if the size of the string plus the size of what you plan on inserting is over '5', then do something else.
For enlightenment on why, read up on the "zero one infinity rule".
This code throws exception just after execution of one iteration of 'for' loop. There might be better ways to copy one string to another.
Your code throws an exception because you are trying to replace the first character of str_new with a different character, but your object doesn't have a first character to replace.
But I want to copy it as mentioned below. Can someone tell me how to fix the bug, or below code cannot be fixed as its totally messed up?
Why do you want to use that for loop? That again leads me to believe this is some sort of homework assignment, because this is definitely not a good way to copy one string into another. A simple assignment is all that is necessary:
string str_new = str_old;
But I get it, you want to use the for loop and you don't even want a loop based on the actual size of str_old. Here you go:
string str_old = "abcde";
string str_new(5, 0);
assert(str_old.size() >= 5);
for (int i = 0; i < 5; ++i) {
str_new[i]= str_old[i];
}
The above code creates a string str_new that has five elements in it that are all equal to 0. It then checks to make sure that str_old actually is 5 characters long. Then it replaces each 0 with a copy of the character at the corresponding position in str_old.
Don't put that kind of code in a real program, but if it satisfies the homework assignment, then go for it.
Why don't you do
string.reserve()
If you want initialized a string of the right capacity, you can do
string.resize()
void resize (size_t n);
void resize (size_t n, char c);
Resize string
Resizes the string to a length of n characters.
void reserve (size_t n = 0);
Request a change in capacity
Requests that the string capacity be adapted to a planned change in size to a length of up to n characters.
If n is greater than the current string capacity, the function causes the container to increase its capacity to n characters (or greater).
The following code seems to be running when it shouldn't. In this example:
#include <iostream>
using namespace std;
int main()
{
char data[1];
cout<<"Enter data: ";
cin>>data;
cout<<data[2]<<endl;
}
Entering a string with a length greater than 1 (e.g., "Hello"), will produce output as if the array were large enough to hold it (e.g., "l"). Should this not be throwing an error when it tried to store a value that was longer than the array or when it tried to retrieve a value with an index greater than the array length?
The following code seems to be running when it shouldn't.
It is not about "should" or "shouldn't". It is about "may" or "may not".
That is, your program may run, or it may not.
It is because your program invokes undefined behavior. Accessing an array element beyond the array-length invokes undefined behavior which means anything could happen.
The proper way to write your code is to use std::string as:
#include <iostream>
#include <string>
//using namespace std; DONT WRITE THIS HERE
int main()
{
std::string data;
std::cout<<"Enter data: ";
std::cin>>data; //read the entire input string, no matter how long it is!
std::cout<<data<<std::endl; //print the entire string
if ( data.size() > 2 ) //check if data has atleast 3 characters
{
std::cout << data[2] << std::endl; //print 3rd character
}
}
It can crash under different parameters in compilation or compiled on other machine, because running of that code giving undefined result according to documentaton.
It is not safe to be doing this. What it is doing is writing over the memory that happens to lie after the buffer. Afterwards, it is then reading it back out to you.
This is only working because your cin and cout operations don't say: This is a pointer to one char, I will only write one char. Instead it says: enough space is allocated for me to write to. The cin and cout operations keep reading data until they hit the null terminator \0.
To fix this, you can replace this with:
std::string data;
C++ will let you make big memory mistakes.
Some 'rules' that will save you most of the time:
1:Don't use char[]. Instead use string.
2:Don't use pointers to pass or return argument. Pass by reference, return by value.
3:Don't use arrays (e.g. int[]). Use vectors. You still have to check your own bounds.
With just those three you'll be writing some-what "safe" code and non-C-like code.
Hey everyone, thanks for taking the time to address my problem. I've looked at so much material at this point that I've just started getting more and more confused. Basically, I'm writing a simple segment of code that parses a string. Please understand that my question is NOT about parsing. I am using C++ and have never used C before and possess a little bit of c++ experience (introductory experience, I'm still a newbie).
struct parsedString{
char chunk1[50];
char chunk2[10];
char chunk3[50];
};
main(char* bigstring)
{
parsedString ps;
ps = parseMe(bigString)
cout << ps.chunk1 << endl;
cout << ps.chunk2 << endl;
cout << ps.chunk3 << endl;
}
parsedString parseMe(char* stringToParse)
{
char* parseStr = stringToParse;
parsedString ps;
ps.chunk1 = first x chars;
ps.chunk2 = next y chars;
ps.chunk3 = last z chars;
return ps;
}
Obviously this is not working code, I didn't want to throw up all the extra stuff since it would be tougher to read through and I'm pretty sure my problem is a newbie c/c++ problem and something about memory allocation or something like that...
Basically when the main function gets to printing the strings from the parsedString it prints out exactly what I want it to, plus garbage characters. I'm entering the values for each array ps.chunk using
ps.chunk1[i] = *parseStr
since parseStr gets me each individual character. I can't figure out where the garbage characters are coming from, does it have something to do with how I am accessing the big string? Originally I used char in the struct instead of arrays and when I printed from within the parseMe() function they would come out great but they would turn into gibberish when I accessed it from the main function. Any help is appreciated, thanks so much.
If something is unclear please let me know I'll do my best to elaborate.
It's not clear why you're trying to do this with '\0' terminated
strings, when C++ has a perfectly usable string class, but
supposing some pedagogical reasons: are your strings '\0'
terminated? How do you extract and copy the first x chars into
ps.chunk1? How do you ensure that it has a '\0'?
If you really want to get exactly n characters, you have to:
assert(strlen(parseStr) >= n);
, copy them into the target (which must contain at least n+1 char's),
memcpy(ps.chunk1, parseStr, n);
, and add the final '\0':
ps.chunk1[n] = '\0';
(And, of course, advance parseStr: parseStr += n;)
Or you can simply use std::string everywhere, and write
something like:
ps.chunk1(stringToParse.substr(startPosition, length));
As pointed out by others, you should use std::string to represent strings, and save yourself all the trouble. This could look like this:
struct parsedString{
std::string chunk1;
std::string chunk2;
std::string chunk3;
};
parsedString parseMe(const std::stirng & stringToParse) {
parsedString result;
// just an example - this assigns the first two characters of stringToParse
// to chunk1
result.chunk1 = stringToParse.substr(0, 2);
// get the other chunks
return result; // return the result
}
The above code should illustrate the usage. You can find more information on std::string here.
This could be happening due to a couple of reasons.
When you declare parsedString ps; it would be good to initialize the structure and make sure that you are receiving clean memory blocks to work with.parsedString ps = {0}; Some platforms don't do this and it's up to you to zero the memory before using it.
char* strings must end with the \0 character. This character signals the end of a char*. This is mandatory! Not inserting it at the end of the string will most probably make the print operation (for instance) display contents beyond the limits of the array giving you garbage characters. This is automatically achieved by zeroing all the struct as I suggest above.