String output gives weird letters - c++

#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
string s = "Too many tags";
for(int i = 0; i < s.size(); i++){
if(!(isspace(s[i]))){
s[i] = '#' + s[i];
}
}
cout << s << endl;
return 0;
}
I'm trying to make a program which adds # tag before each letter in the string, but on output I get weird letters.. where is my mistake?

s[i] = '#' + s[i];
modifies the value of an existing character. If you want to add new characters into your string, you should use insert:
s.insert(i, "#");
As Mark Ransom points out, you also need to move one further char through your string to avoid constantly adding "#" before the same letter. You could do this using
s.insert(i++, "#");
Note that you could always take VladimirM's advice and make slightly larger changes to something like
int i=0;
while (i<s.size()) {
if (!isspace(s[i])) {
s.insert(i++, "#");
}
i++;
}

This line:
s[i] = '#' + s[i];
isn't doing what you think it is. s[i] is a char, # is also a char. Adding these together doesn't give you the concatenation of the two characters, it gives you the addition of the integer code of the characters (so 35 for # and the ASCII code for whatever s[i] happens to be).

I add more: I think the simpler way is to use temporary variable otherwise your loop with 'insert' will go to endless loop and will hang:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
string s = "Too many tags";
string res = "";
for(int i = 0; i < s.size(); i++){
if(!(isspace(s[i]))){
res += "#";
}
res += s[i];
}
cout << res << endl;
return 0;
}

Related

Reversing each word in a string without changing the order in C++

I am writing a code in C++ to reverse all the words in a string without changing the order of the list
This is my code:
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s = "God Ding";
int n = s.size();
int i = 0, j = 0;
while(j < n){
if(s[j] == ' ' || j == n-1){
reverse(s.begin()+i, s.begin()+j);
j++;
i = j;
}
else{
j++;
}
}
cout << s;
return 0;
}
Expected Output: "doG gniD"
My output: doG Ding
2nd input: "Let's take LeetCode contest"
Expected Output: "s'teL ekat edoCteeL tsetnoc"
My Output: "s'teL ekat edoCteeL contest"
Everything is working fine but only the last word is not getting reversed
You need either to detect in your if the special situation of processing the last character, or add an extra reverse after the while, if the last word was not processed (i.e. the last char was not a space).
In your case, you've added the detection of last character, but did not process the reverse before the increment, as would be the case if the word ended with a space. To correct this situation, you must take into account this special situation:
if(s[j] == ' ' || j == n-1){
reverse(s.begin()+i, s.begin()+j+(j==n-1?1:0));
// ^ (if it's last, take +1)
...
I think this would be a better implementation for your code:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string s = "God Ding", reversed_string;
std::string word;
std::istringstream ss(s); // Declaring an in string stream
while (std::getline(ss, word, ' ')) // Here getline gets every word in ss and stores it in the variable 'word'
{
// This loop reverses the variable 'word'
for (int i = word.size() - 1; i >= 0; i--)
{
reversed_string.push_back(word[i]);
}
reversed_string.push_back(' ');
}
std::cout << reversed_string;
return 0;
}
Also look up to why is "using namespace std" considered as a bad practice.
Here you have a working example:
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string s = "God Ding";
int i = 0;
int j = 0;
while (i <= s.length()) {
if (i == s.length() || s[i] == ' ') {
std::reverse(s.begin() + j, s.begin() + i);
j = i + 1;
}
i++;
}
std::cout << s << std::endl;
return 0;
}
I changed a lot of things.
These are the issues you need to fix:
Make your loop go beyond the last char.
Reverse if j (from your code) is beyond the last char.
In order to reverse a word, you need i to index the first char, and j to index the char after the last one.
However, your loop exits whenever j indexes the char after the last one. That's why it never reverses the last word.
The simplest fix is to do one more check after the loop exits, and reverse the last word if there is one:
while(j < n) {
if(s[j] == ' ') { // remove the `j==n-1` test
reverse(s.begin()+i, s.begin()+j);
j++;
i = j;
} else {
j++;
}
}
if(i < j) {
reverse(s.begin()+i, s.begin()+j);
}
The alternative would be to rewrite the loop in some way that finesses the problem. I don't really recommend this, given that you have something that almost works and that you know how to fix.

Unexpected return from cin.getline() in C++

I have this problem that when I use getline() function to input a char array it also inserts other characters, that are not constant and change every time I run the program.
I do realize it is most likely because of some kind of overflow happening, and it just takes numbers from the RAM.
But is there a possibility to fix that?
(Program is supposed to reverse a string and remove any non-letters, excluding spaces)
Here is my program:
#include <iostream>
#include <ctype.h>
#include <string>
using namespace std;
int main() {
string decoded = "";
char text[100];
cin.getline(text,sizeof(text));
for(int i = sizeof(text)-1; i >= 0; i--){
if (isalpha(text[i]) || text[i] == ' ' )
decoded.push_back(text[i]);
}
cout << decoded;
return 0;
}
Add #include <string.h> and change
for(int i = sizeof(text)-1; i >= 0; i--){ to
for(int i = strlen(text)-1; i >= 0; i--){
because strlen(text) calculates length upto \n where as sizeof(text) includes \n too.
or as Ruks mentioned in the comment a simple initialization char text[100] {}; works.
Just declare text as an empty array same as char[] text = new char[]{};

How do you insert characters into middle of string? C++

The purpose of this code is to insert an x in between repeating letters. For example, if I were to input "CoolBoolFallmoose", the output would be "CoxolBoxolFalxlmoxose".
The code is also supposed to make an even number of pairs of letters, so if there is an odd amount of characters, an x is added to the end of the string. An example for this would be if we had "ball", it would become "balxlx" to make even pairs: "ba" "lx" "lx".
This is the code I have so far:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(){
string cipher, plain, paired = "";
cout << "input plaintext(no spaces, lowercase):\n";
cin >> plain;
for (int i=0;i<plain.length();i++){
if (plain[i]==plain[i+1]){
plain.insert(i,'x');
}
paired[i]=paired[i];
cout<<paired[i];
}
if (paired.length() % 2!= 0){
paired=+'x';
}
cout<<paired<<endl;
return 0;
}
The output I get is just the same as my input, no "x" added in any place.
The issue I am having is, every time I try to use the append() or insert() function for strings, I get an error from my compiler, which is xCode. Is there another way to solve this code?
EDIT: The error says:
No matching member function to call for insert
It also comes up for append().
I don't really know what you wanted to do with this part:
paired[i]=paired[i];
cout<<paired[i];
but otherwise the logic is good. Here is my take on it, x is a counter:
#include <iostream>
#include <string>
using namespace std;
int main(){
string m,n;
int x = 0;
cout << "Input: " << endl;
getline(cin, m);
for(int i = 0;i < m.length();i++){
x++;
n = n + m[i];
if(m[i] == m[i+1]){
n = n + 'x';
x++;
}
}
if((x % 2) != 0){
n = n + 'x';
}
cout << n;
return 0;
}
If you look at the available overloads of std::string::insert(), you will see that your statement plain.insert(i,'x'); does not match any of them, hence the compiler error. The overloads that takes a single char require either:
an index and a count (you are omitting the count)
an iterator and an optional count
There is, however, a couple of overloads that take just an index and a value, but they require a const char* or a std::string, not a single char.
Also, paired[i]=paired[i]; is a no-op. Except in your case, since paired has a size() of 0 since you never append anything to paired, so actually any access to paired[...] is undefined behavior.
Try this instead:
#include <iostream>
#include <string>
using namespace std;
int main(){
string plain, paired;
cout << "input plaintext(no spaces, lowercase):\n";
cin >> plain;
paired = plain;
for (string::size_type i = 1; i < paired.size(); ++i){
if (paired[i] == paired[i-1]){
paired.insert(i, 1, 'x');
// or: paired.insert(paired.begin()+i, 'x');
// or: paired.insert(i, "x");
// or: paired.insert(i, string{'x'});
// or: paired.insert(paired.begin()+i, {'x'});
++i; // skip the x just inserted
}
}
if (paired.size() % 2 != 0){
paired += 'x';
}
cout << paired << endl;
return 0;
}
Demo
A couple of points
First, Although the string.insert function says it takes an int as its first argument it really wants an iterator in this case.
Second, you are inserting elements into your "plain" string which increases its length and you have plain.length within your loop so you create an infinite loop.
Third, insert inserts BEFORE the index so you need to add 1 to I.
The code below will work for your loop:
Int len = plain.length();
Int count = 0;
for (int i = 0; i < len + count; i++)
{
If (plain[i] == plain[i + 1])
{
plain.insert(plain.begin() + (i +1), 'X');
++count;
}
}
cout << plain;
And as, mentioned below, if you want to handle spaces you can use getline(cin, plain) instead of cin.

I have a char array and I want to insert two more spaces for each space

My logic is as follows :
#include<bits/stdc++.h>
using namespace std;
int main(){
char a[50] = {'h','i',' ','m','e',' ','t','e'};
// k = 4 because i have 2 spaces and for each
// space i have to insert 2 spaces . so total 4
//spaces
int k=4;
for(int i=strlen(a)-1 ; i>0 && k >0 ; i--){
if(a[i] != ' ')
{
a[i+k] = a[i];
a[i] = ' ';
}
else
{
k = k - 2;
}
}
printf("%s" , a);
return 0;
}
I have to character array to solve it. I am able to
do it using string stl
The output i get is
hi---me.
But the answer is
hi---me---te.
Your code is tagged C++. But there is nothing C++ in your code. It is pure C.
And, your are including #include<bits/stdc++.h> and using the std namespace using namespace std;. From now on: Please never ever in your whole life do such things again. Or, stop working with C++.
Additionally never ever use plain C-style array like your char a[50] in C++.
In your code you have some bugs. Most critical is the missing terminating 0 and then calling strlen. Before you use a function, always check somewhere, how this function works. Use meaningful variable names. Write comments. Always check boundaries.
I updated your C-Code:
#include <stdio.h>
int main()
{
// Character String to work on
char charString[50] = "hi me te";
// Check all possible positions in string
for (int index = 0; (index < 49) && (0 != charString[index]); ++index)
{
// If there is a space in the string
if (' ' == charString[index])
{
// Shift all characters one position to the right
for (int shiftPosition = 48; shiftPosition >= index; --shiftPosition)
{
charString[shiftPosition + 1] = charString[shiftPosition];
}
++index;
}
}
// Show result
printf("%s\n", charString);
return 0;
}
And here the C++ solution
#include <iostream>
#include <string>
#include <regex>
int main()
{
// Text to work on
std::string text("hi me te");
// Replace every space with 2 spaces. Print result
std::cout << std::regex_replace(text, std::regex(" "), " ");
return 0;
}

`std::swap` doesn't work as intended in string manipulation

I have tried to make basic string encryption, by swapping two consecutive letters.
And it didn't really work as I intended.
#include <iostream>
#include <string.h>
#include <algorithm>
int main()
{
std::string str = "This is a simple string.";
for (int i = 0; i <= str.length(); i++) {
std::swap(str[i], str[i + 1]);
}
std::cout << str;
std::cin.get();
}
I want to actually swap two near letters, so it will look like encrypted.
The Current result is
his is a simple string.
First of all, you have out of bound access because of
for (int i = 0; i <= str.length(); i++)
// ^^^^
hence the behavior of your program is undefined.
You want to iterate one past the size of the string. In addition to that, loop only if the string is not empty(credits #jww).
Secondly, there is a comparison between int and unsigend int(i.e. str.length()) which is also not you want.
Last but not least, add the proper header for std::string(as #PaulMcKenzie pointed out in the comments).
Altogether, you probably want this
#include <string>
for (std::size_t i = 0; !str.empty() && i < str.size()-1; i += 2) {
// ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^
std::swap(str[i], str[i + 1]);
}
I think you were aiming for something like:
std::string str = "This is a simple string.";
for (int i = 0; i <= str.length()-2; i+=2)
{
std::swap(str[i], str[i + 1]);
}
std::cout << str;
with output
hTsii s aispmels rtni.g