The question requires to output the input following the rules below:
1. if the input character is between A-Z, or a-z, the out put character would be
the following letter, abc-->bcd
2. if the input is Z or z, the output would be A or a, z->a,Z->A
3. if the input is space, then it remains the same
4. if the input is anything else, increment its ascii value by 1, and print.
This is an example:
input: abcZ ]
output: bcdA ^
Here is my code:
#include <iostream>
using namespace std;
int main()
{//use ASCII to get a code for input by changing a to b, b to c....z to a, space remain the same, everything else ++
char c,d;
int i=0;
for(i=0;;i++)
{
if (('A' <= (c=cin.get()) < 'Z')||('a' <= (c=cin.get()) < 'z'))
{
d=c+1;
}
else if(c=cin.get()==32)// ascii value of space is 32
d=c;
else if((c=cin.get())=='Z')
d='A';
else if((c=cin.get())=='z')
d='a';
else
{
c++;
d=c;
}
cout<<d;
}
cout<<endl;
return 0;
}
This is the output:
What I am thinking is that β is the output of enter key, but I dont want an output for enter key.
space,Z and z don't convert properly either.
Can anyone help me with the code?Thank you.
You've got a bunch of problems here. Here are some hints:
1) Call cin.get() just once per loop iteration. That is:
for (...)
{
c = cin.get();
// do not call cin.get() beyond this point.
// use the c variable instead
...
}
2) Be careful around your compound conditionals.
Instead of: ('A' <= c < 'Z'), you really want: ('A' <= c && c < 'Z')
3) Add another condition to check for 10. This is the code for the line feed character. If this is detected, just do a cout << endl
There are a number of ways to simplify the logic here too. Keep trying!
Related
#include<iostream>
#include<string>
using namespace std;
string pass(string a){
int i=0;
string c[100];
char d;
while(a[i]!='\0'){
d = a[i];
if(d>='a'&& d<='z'){
d++;
c[i]=d;
}
else if(d>='A' && d<='Z'){
d++;
c[i]=d;
}
else{
c[i]=d;
}
i++;
}
for(int k=0; k<i; k++){
cout<<c[k];
}
}
int main(){
string x;
getline(cin,x);
pass(x);
return 0;
}
This is my solution.
I was looking for this kind of problem for a while but all I got was for pre-defined inputs. So, I passed a string from the main function.
I used a while loop to store every letter with the following letter (EX "a -> b") in another array "c". I then print the copied array using a loop.
Can we make it shorter?
You don't need to create a separate array called c. You can create an output string and iterate through it and increment the characters as shown below:
int main()
{
std::string input;
std::getline(std::cin, input);
std::string output(input);
for(char &c: output)
{
++c;
}
std::cout<<"input was: "<<input<<std::endl;
std::cout<<"changed string is: "<<output<<std::endl;
}
This is probably a better (and shorter) implementation for your code:
#include<iostream>
#include<string>
char NextAlpha(char character)
{
if (character == 'Z') return 'A';
else if (character == 'z') return 'a';
return character + 1; // Can be replaced by 'char((int)character + 1);'
}
int main() {
std::string input;
getline(std::cin, input);
for (int i = 0; i < input.size(); i++)
{
input[i] = NextAlpha(input[i]);
}
std::cout << input;
return 0;
}
The NextAlpha function returns the next alphabet by adding 1 to the character, but a more understandable version of it will be firstly converting the given character into an int as such:
(int)character
..which basically means getting the ascii value of that character. Now we add 1 to the int:
(int)character + 1
..and then convert it back to char
char((int)character + 1)
..but here I've not used this way because ++character looks a lot more cleaner.
The exceptions are defined before the return statement.
In the main function, we have a loop that iterates through all of the characters in the given string, and for each character, it does the following:
// Set the character at index 'i' of string 'input' to the next character in the alphabet.
input[i] = NextAlpha(input[i]);
Also, consider not using the following in your code:
using namespace std;
..as it's considered as bad practice.
First, you have an error in your code: your pass function is declared as returning a string but it doesn't return anything. Actually, you don't need to return anything β just pass the string by reference and make any required changes to its content "in place".
Second, you should be aware that the C++ Standard does not require that the Latin letters (lower- and upper-case) be represented by contiguous, sequential values (though in the ASCII system, used in most implementations today, they are).1
Third, you don't need so many loops, and you don't need to repeat the c[i]=d; statement in the if, else if and else blocks.
I'm not sure what you want to do with the 'z' and 'Z' characters but, in the code below, I'm assuming these should "wrap around", to 'a' and 'A', respectively.
So, here's a way to do what you want more concisely, and which doesn't depend on the implementation's specific representation values for Latin letters:
#include<iostream>
#include<string>
void pass(std::string& a) // Pass by reference (using "&") - changes will be kept.
{
const std::string Lowers{ "abcdefghijklmnopqrstuvwxyz" };
const std::string Uppers{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
size_t p;
for (auto& c : a) { // Note the "&" again: changes to c will be reflected in the corresponding "a" element
if ((p = Lowers.find(c)) != std::string::npos) {
c = Lowers[++p % 26]; // 'z' wraps round to 'a'
}
if ((p = Uppers.find(c)) != std::string::npos) {
c = Lowers[++p % 26]; // 'Z' wraps round to 'A'
}
}
}
int main()
{
std::string x;
std::getline(std::cin, x);
pass(x);
std::cout << x << std::endl;
return 0;
}
I have moved the output of the transformed string to the main function (and simplified it somewhat); generally, a function should do only the task it is set β which, in this case is to make the transformation. The subsequent display of the transformed string should be left to the calling module.
1 The EBCDIC system, for example, doesn't have the Latin letters in a contiguous sequence. You could use the std::islower(), std::isupper() and/or std::isalpha() functions to check for letters, but you would still need some sort of "data table" to determine what the 'next' character should be, unless you assume an ASCII or compatible encoding system.
I am given a string and I have to remove a substring from it. Namely WUB, and replace it with a space character.
There are 2 WUB's between ΓRE' and 'THE'. SO the first condition in if statement is for not printing two blank spaces but on executing the code two blank spaces are being printed.
Input: WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Output: WE ARE THE CHAMPIONS MY FRIEND
Here is my code so far:
#include <iostream>
using namespace std;
int main()
{
const string check = "WUB";
string s, p;
int ct = 0;
cin >> s;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
{
i += 2;
if (p[ct] == '32' || p.empty())
{
continue;
}
else
{
p += ' ';
ct++;
}
}
else
{
p += s[i];
ct++;
}
}
cout << p;
return 0;
}
Why is the first if statement never executed?
2 things are going to break your code:
you are doing a for loop like this int i=0;i<s.size() but reading (s[i]=='W' && s[i+1]=='U' && s[i+2]=='B')
and here: if(p[ct]=='32') you mean for sure if(p[ct]==32) or if(p[ct]==' ')
This condition
if(p[ct]=='32')
should read either
if(p[ct]==32)
or
if(p[ct]==' ')
that is, compare to the numeric value of the space character or to the space character itself.
Additionally, when your i grows close to the string's length, the subexpressions s[i+1] and s[i+2] may reach non-exiting characters of the string. You should continue looping with a i<s.length()-2 condition.
EDIT
For a full solution you need to fully understand the problem you want to solve. The problem statement is a bit vague:
remove a substring ("WUB") from (a given string). And put a space inplace of it if required.
You considered the last condition, but not deeply enough. What does it mean, 'if required'? Replacement is not required if the resulting string is empty or you appended a space to it already (when you encounter a second of further consecutive WUB). It is also not necessary if you are at WUB, but there is nothing more following it - except possibly another WUBs...
So, when you find a "WUB" substring it is too early to decide if a space is needed. You know you need a space when you find a non-WUB text following some WUB (or WUBs) and there was some text before those WUB(s).
There are actually three bugs here, so it's probably worth to conclude them in one answer:
The first condition:
if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
is out of bounds for the last two characters. One fix would be to check the length first:
if(i < s.length() - 2 && s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
There's a multicharacter-literal in
if (p[ct] == '32' || p.empty())
Use ' ' or 32 or std::isspace instead. IMO the last one is the best.
In the same condition
p[ct] == '32'
is always out of bounds: ct is equal to p.length(). (Credits to Some programmer dude, who mentioned this in the comments!) The variable ct is also redundant, since std::string knows it's length. I suggest to use std::string::back() to access the last character and reorder the condition as so:
if (p.empty() || std::isspace(p.back()))
The algorithm to this program is on the right track.
However, there is a few issues..
The for loop goes out of index. A way to solve this issue is substracting the size -3. Something like this.
for (int i=0; i<s.size()-3; i++) {
}
I do not suggest using other variables as counters like ct. In this case ct can reach an index out of bound error by using p[ct] inside the for loop.
Creating a string and using append() function will be a better solution. In this case, we iterate through each character in the string and if we find "WUB" then we append a " ". Otherwise, we append the character.
I highly recommend to write the first if() statement using substring() from C++.
This makes the code easier to read.
Substring creates and returns a new string that starts from a specific position to an ending position. Here is the syntax
syntax: substr(startingIndex, endingIndex);
endingIndex is exclusive
#include <string>
#include <iostream>
int main() {
string s, p;
cin >> s;
for(int i=0;i<s.size()-3;i++) {
if (s.substr(i, i+3) == "WUB") {
p.append(" ");
} else {
p.append(s.substr(i,i+1));
i++;
continue;
}
i+=3;
}
}
I need to design a character counter, whenever I enter single char. it gives me the next one in succession e.g. enter A, it shows B, Z-->A for both lower and Upper letters. only using (for loop)
What went wrong?
The characters doesn't show in order I mean whenever I enter a letter it's random response giving me a random number that hasn't any function of the program the body looks acceptable but in turns of internal details something isn't going the way I wanted to be. Here's my code:
char count[256];
int size = 0;
for ( c != 0; ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) ; c++ )
{
size += count[c];
}
return size;
return 0;
using ASCI codes will be helpfull here
for e.g
char alphabet ;
cout <<"Enter alphabet"<<endl;
cin>>alphabet ;
int a = (int) alphabet;
a++;
cout<<"Next alphabet is :"<<(char)a<<endl ;
Take your input
Check if it is an alphabet
Check if it is a 'z' or 'Z', if so, make it an 'a', or 'A' (hint: use ascii codes and a little arithmetic)
Else add a character to it
Print
I was going over this code to read a file on my desktop that decrypts a cesar cipher code and I am stuck trying to figure out how the shift is calculated in this program.
From what I can tell, Max e's is the shifted letter with the highest frequency. Since e's are the most common letter in English, the program is trying to set the highest frequency char in the cipher, to an 'e' in English. Which is good, as far as it goes, but there are many phrases where e's are NOT the most frequent letter, and then it will fall on it's face.
So, how can I tell the program to guess at the most frequent cipher letter to be an e in plain text BUT in case it isn't, then proceed to try an e shifted to the second most frequent letter in the text, and so on, until I find it?
A friend helped with that part but has poor English so it is difficult for him to explain it to me. Can someone please elaborate? Assistance is greatly appreciated! Let me know what you think:
#include <iostream>
#include <string>
#include <cctype> // isalpha, islower, isupper, functions
#include <fstream>
using namespace std;
string caesarShift(string text, int shift);
int main()
{
int maxEs = 0; // # of e's in maxString
int currentEs = 0; // # of e'sin currentString
string maxString; // decrypted caesar shift with most e's
string currentString; //decrypted caesar shift
string cipher; // Stores cipher text
char ch; // Stores currentcharacter for reading
ifstream fin("/Users/jasonrodriguez/Desktop/encrypted.txt"); //opens "encrypted.txt" file
while( fin.get(ch) ) // readseach char into the cipher till EOF
{
cipher += ch;
}
fin.close(); // be safe andclose file
for(int i=0; i < 26; i++)
{
currentEs =0; // Reset counter
currentString =caesarShift(cipher, i); // get shifted text
for(unsigned int x=0; x <currentString.size(); x++) // check each character of stringarray
{
if(currentString[x] == 'e' || currentString[x] == 'E') // check fore's
{
currentEs++; // increment Ecounter
}
}
if(currentEs > maxEs) //if currentEs is greater than maxEs, replace max with current
{
maxEs =currentEs;
maxString= currentString;
}
}
cout << maxString << endl;
return 0;
}
/**
string caesarShift(string text, int shift)
Decrypts Caesar Shift using text and shift
*/
string caesarShift(string text, int shift)
{
shift = shift % 26; // Morethan 26 is redundant and unneeded
char ch = 0; // holds current character
char chs = 0; // holds shiftedcharacter
for(unsigned int i=0; i < text.size();i++)
{
ch = text[i];
if( isalpha(ch) )
{
chs = ch -shift; // reverse shifting
if( (islower(ch) && chs < 'a' ) // If is lowercase andshifted value is lower than 'a'
||
( isupper(ch) && chs < 'A' ) ) // Ifis uppercase and shifted value is lower than 'A'
{
chs += 26; // Add 26(number ofletters) to get back to the correct place in alphabet
}
text[i] =chs; // Set character to shifted character
}
}
return text;
}
Questions:
From what I can tell, Max e's is the shifted letter with the highest frequency. Since e's are the most common letter in English, the program is trying to set the highest frequency char in the cipher, to an 'e' in English. Which is good, as far as it goes, but there are many phrases where e's are NOT the most frequent letter, and then it will fall on it's face. So, how can I tell the program to guess at the most frequent cipher letter to be an e in plain text BUT in case it isn't, then proceed to try an e shifted to the second most frequent letter in the text, and so on, until I find it?
I think if I shift a character by a shift amount the character may or may not be out of bounds. 'a' + 3 is 'd' ok, 'x' + 3 is '{' not ok. So if the character is over 'z' take away 26, if under 'a' add 26. can be a usable function. However, can you please explain to me how the shift is calculated in the program and is applied it to the file? It has me totally stumped :(
Calculating a shift:
First, you need to mapy the letters 'A' through 'Z' (assuming only uppercase letters) to the integers 0 through 25. C++ let's you do this easily with subtraction:
n = c - 'A';
Now you can perform the shift with modulus arithmetic:
n = (n + shift) % 26;
Finally map back to a letter:
p = n + 'A';
(Note that you will need apprporiate declarations for the variables used in these examples. I suggest that you use more meaningful names than the single-letter variables names I use.)
I'm creating a Caesar Cipher in c++ and i can't figure out how to increment a letter.
I need to increment the letter by 1 each time and return the next letter in the alphabet. Something like the following to add 1 to 'a' and return 'b'.
char letter[] = "a";
cout << letter[0] +1;
This snippet should get you started. letter is a char and not an array of chars nor a string.
The static_cast ensures the result of 'a' + 1 is treated as a char.
> cat caesar.cpp
#include <iostream>
int main()
{
char letter = 'a';
std::cout << static_cast<char>(letter + 1) << std::endl;
}
> g++ caesar.cpp -o caesar
> ./caesar
b
Watch out when you get to 'z' (or 'Z'!) and good luck!
It works as-is, but because the addition promotes the expression to int you want to cast it back to char again so that your IOStream renders it as a character rather than a number:
int main() {
char letter[] = "a";
cout << static_cast<char>(letter[0] + 1);
}
Output: b
Also add wrap-around logic (so that when letter[0] is z, you set to a rather than incrementing), and consider case.
You can use 'a'+((letter - 'a'+n)%26);
assuming after 'z' you need 'a' i.e. 'z'+1='a'
#include <iostream>
using namespace std;
int main()
{
char letter='z';
cout<<(char)('a' + ((letter - 'a' + 1) % 26));
return 0;
}
See this https://stackoverflow.com/a/6171969/8511215
Does letter++ work?
All in all char is a numeric type, so it will increment the ascii code.
But I believe it must be defined as char letter not an array. But beware of adding one to 'Z'. You will get '[' =P
#include <iostream>
int main () {
char a = 'a';
a++;
std::cout << a;
}
This seems to work well ;)
char letter = 'a';
cout << ++letter;
waleed#waleed-P17SM-A:~$ nano Good_morning_encryption.cpp
waleed#waleed-P17SM-A:~$ g++ Good_morning_encryption.cpp -o Good_morning_encryption.out
waleed#waleed-P17SM-A:~$ ./Good_morning_encryption.out
Enter your text:waleed
Encrypted text:
jnyrrq
waleed#waleed-P17SM-A:~$ cat Good_morning_encryption.cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
//the string that holds the user input
string text;
//x for the first counter than makes it keeps looping until it encrypts the user input
//len holds the value (int) of the length of the user input ( including spaces)
int x, len;
//simple console output
cout << "Enter your text:";
//gets the user input ( including spaces and saves it to the variable text
getline(cin, text);
//give the variable len the value of the user input length
len = (int)text.length();
//counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than len
for(x = 0; x < len; x++) {
//checks each letts (and spaces) in the user input (x is the number of the offset keep in mind that it starts from 0 and for example text[x] if the user input was waleed would be w since its text[0]
if (isalpha(text[x])) {
//converts each letter to small letter ( even though it can be done another way by making the check like this if (text[x] =='z' || text[x] == 'Z')
text[x] = tolower(text[x]);
//another counter that loops 13 times
for (int counter = 0; counter < 13; counter++) {
//it checks if the letts text[x] is z and if it is it will make it a
if (text[x] == 'z') {
text[x] = 'a';
}
//if its not z it will keeps increamenting (using the loop 13 times)
else {
text[x]++;
}
}
}
}
//prints out the final value of text
cout << "Encrypted text:\n" << text << endl;
//return 0 (because the the main function is an int so it must return an integer value
return 0;
}
Note: this is called caeser cipher encryption it works like this :
ABCDEFGHIJKLMNOPQRSTUVWXYZ
NOPQRSTUVWXYZABCDEFGHIJKLM
so for example my name is waleed
it will be written as : JNYRRQ
so its simply add 13 letters to each letter
i hope that helped you
It works but don't forget that if you increment 'z' you need to get 'a' so maybe you should pass by a check function that output 'a' when you get 'z'.
cast letter[n] to byte* and increase its referenced value by 1.