Why the white spaces are ignored when converting to encrypted message? - c++

The Program should print the expected messages as expected but its not printing.
Plain Text message: Hello! how are you?
Expected encrypted message: Glqqv! bvc Rfl avm?
The program is printing: Glqqv!bvcRflavm
White spaces are totally ignored. How to fix it?
The Code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string alphabet {"!A2BCDEFGHIJ#KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"};
string key {"!X2ZNLWEBGJHQDYVTK2F#UOMPCIASRxznlwebgjhqdyvtkfuompciasr"};
string secret_message{};
string encrypted_message{};
cout << "Enter your secret message: ";
getline(cin, secret_message);
cout << "'nEncrypting message.... ";
for (char c: secret_message)
{
float position = alphabet.find(c);
if(position != string::npos)
{
char new_char {key.at(position)};
encrypted_message += new_char;
}
}
cout << "\n Encrypted message is: "<< encrypted_message << '\n';
cout << "\n\n" << '\n';
return 0;
}

' ' is not part key.
To handle c not found in key and remain unchanged, add an else statement.
float position = alphabet.find(c);
if(position != string::npos) {
char new_char {key.at(position)};
encrypted_message += new_char;
} else // add
encrypted_message += c;
}
Recommend using type size_type as that is the type returned by .find() and used by .at().
// float position = alphabet.find(c);
std::string::size_type position = alphabet.find(c);

Float position = alphabet.find(c); //float is not making errors reading/printing the full line catch, but recommended you use an integer type instead.
Fix
size_t position = alphabet.find(c); //size_t fixed your issue an un-initialized int and You also forget to complete your if statement in the end by adding the function to set the position of encrypted_message to c as you assigned to be:
else
encrypted_message += c;
for (char c: secret_message)
{
size_t position = alphabet.find(c);
if(position != string::npos) {
char new_char {key.at(position)};
encrypted_message += new_char;
} else
encrypted_message += c;
}

Related

Find subword included input symbol c++

I want to print a subword, after inputting my symbol.
For example like this.
I want input abcdefghijk d
And get efghijk
This is my code body without condition.
#include <iostream>
int main(){
const int n = 21;
char word[n];
std::cin>>word;
char symbol;
std::cin>>symbol;
int i = 0;
char*p = word;
while(word[i]!='\0' && word[i]!=symbol){
// what condition I need to write here?
i++;
std::cout << p <<std::endl;
}
return 0;
}
Thanks for helping))
You need to move your pointer p to the right while the splitting character is not met.
char*p = word;
while(word[i]!='\0' && word[i]!=symbol){
p++;
i++;
}
p++;
std::cout << p << std::endl;
On the first line, your pointer p points to the begining of the word (i.e. on the first char).
Then the while loop tests every char until we find the splitting char. Everytime a character does not match you splitting character, you increase p and make it point to the next character.
However, you would need to increase it one final time after the loop to point after the splitting char.
Note that a shorter way to do is:
char*p = word;
while(word[i]!='\0' && word[i]!=symbol){
i++;
}
p = p + i + 1;
std::cout << p << std::endl;
You could try something like this:
int main()
{
std::string text;
std::cout << "Enter sentence: ";
std::getline(std::cin, text);
char split_char;
std::cout << "Enter subword / split character: ";
std::cin >> split_char;
std::string::size_type split_position = text.find(split_char);
std::string::size_type word_end_position = text.find_first_of(" \t", split_position);
if (word_end_position == std::string::npos)
{
word_end_position = text.length();
}
std::string split_text = text.substr(split_position, word_end_position, split_position);
std::cout << split_text << "\n";
return 0;
}

how to store user input into array in C++

I am new to C++, and want to ask this basic question
what i want: user input data like 2:3American, 4:2China (this means my country team wins 2 points lose 3 points againts American. my country team win 4 points and China team win 2 points)
in console:
please input the result for your team against other teams, input negative number to exit
2:3American
4:2China
-1
result win:1
lose:1
draw:0
If there is no specific encoding is given to you by some authority, use as simple as possible. A better was "2 3 American 4 2 China". So that you only deal with a simple for loop.
The result line is not calculated. Convert each string to integer to calculate.
int main( int argc, char* argv[]) {
std::vector<std::string> arguments(argv + 1, argv + argc);
std::cout << "arguments contains \n";
for (std::vector<std::string>::iterator it = arguments.begin() ; it != arguments.end(); ++it) {
int firstPos = it->find_first_of(":");
int secPos = 0;
std::string firstInteger = it->substr(0,firstPos);
std::string secondInteger;
if ( firstInteger.compare("-1") == 0 ) {
std::cout << "breaking \n";
return 0;
} else {
std::cout << " f=<" << firstInteger << ">";
secPos = it->find_first_not_of( "012345678:", firstPos);
if ( secPos == std::string::npos )
std::cout << "not found";
std::cout << " s=<" << it->substr(firstPos+1 ,secPos-firstPos-1 ) << "> ";
std::string teamName = it->substr(secPos);
std::cout << teamName ;
std::cout << std::endl;
}
}
std::cout << '\n';
return 0;
}
I've written a code similar to this problem a long time ago. made a small change to solve your problem.
So i think this is what you want
INPUT "2:3American 4:2China -1" (SINGLE LINE)
OUTPUT as expected
#include <iostream>
using namespace std;
size_t non_int(int index,string* s)
{
int i=index;
for( i=index;i<s->length();i++){
if(s->at(i) >= '0' && s->at(i) <= '9')
{
// cout << s->at(i) << " is a Digit";
}
else{
return (i-1)<index?(std::string::npos):(i-1);
}
}
return (i-1)<index?(std::string::npos):(i-1);;
}
int main()
{
cout << "Please input the match result such as 2:3American " << endl;
string str;
std::getline (std::cin,str);
//cout<<str;// i want to see did the first user input stored in array. But seems the console..does not print out temp[0] and just skipt it
int win,lose,draw=0;
std::size_t found = 0;
string s1,s2;
int i1,i2;
std::size_t f1,f2;
while( found !=std::string::npos)
{
f1 = str.find(":",found);
if (f1!=std::string::npos){
i1 = stoi(str.substr(found,f1-found));
f2 = non_int(f1+1,&str);
if (f2!=std::string::npos){
i2 = stoi(str.substr(f1+1,f2-f1));
if(i1>i2) win++;
else if(i1<i2)lose++;
else draw++;
}
else {
cout<<"ERROR :invalid input ";
}
}
else {
//exit on -ve input
// cout<<"ERROR 45 ";
}
found = str.find(" ",found+1);
}
cout<<"win:"<<win<<"lose:"<<lose<<"draw:"<<draw<<endl;
return 0;
}
Step 1:
Define a class that represents an input token.
struct Segment
{
int myCountryScore;
int otherCountryScore;
std::string otherCountry;
};
Step 2
Define an input function that reads a Segment from a stream.
std::istream& operator>>(std::istream& s, Segment& data)
{
Segment tmp;
char sep;
int firstNumber;
bool good = false;
if (s >> firstNumber && firstNumber >= 0)
{
tmp.myCountryScore = firstNumber;
if (s >> std::noskipws >> sep >> tmp.otherCountryScore >> tmp.otherCountry >> std::skipws) && (sep == ':'))
{
// The read worked. Copy it to the output object.
data = tmp;
good = true;
}
}
if (!good) {
// If there was an error reading.
// Or we reached the end (negative number read)
// Then set the state of the stream to failure mode.
s.setstate(std::ios::failbit);
}
return s;
}
Step 3
Write a loop that reads Segments from a stream in a loop.
Segment object;
while(std::cin >> object) {
// You have correctly read an object
// Add your code to handle it here.
}
Step 3 Alternative.
Rather than read the Segment one by one you can copy them into a vector simply using a stream iterator.
std::vector<Segment> data(std::istream_iterator<Segment>(std::cin),
std::istream_iterator<Segment>());

Program Won't Continue to Run When Testing for Palindromes (C++)

I'm a beginner in coding with C++. I'm trying to make a program that completes a specific set of tasks:
opens a data file,
takes each line of the file,
processes each line by removing all whitespace and punctuation,
converts the string into all lowercase,
uses a recursive method to test if the string is a palindrome,
finds a position within the string where characters can be added to make it a palindrome if it isn't already,
then adds the characters needed to make it a palindrome in the position specified in (6).
I'm only allowed to use 4 user-defined functions with specific parameters. So far I've got about 80% of the program to work, but there's an error when it detects a non-palindrome. I'm hoping someone can find out why. Here's my code:
// Read file data, check for palindromes, and process strings to palindromes.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
string process(string);
bool is_palindrome(string);
int palindrome_fix_location(string);
string palindrome_addition(string, int);
int main()
{
ifstream inFile;
inFile.open("data");
string preString;
int palinLoc = 0;
while(getline(inFile, preString))
{
cout << "\nOriginal line: " << preString << endl;
cout << "Processed line: " << process(preString) << endl;
if (is_palindrome(preString) == true)
cout << "Line is palindrome." << endl;
else
cout << "Line is NOT a palindrome." << endl;
palindrome_fix_location(preString);
palindrome_addition(preString, palinLoc);
}
inFile.close();
return 0;
}
// Return a string that is lowercase with no punctuation or spacing.
string process(string preString)
{
string procString;
for (size_t i = 0; i < preString.length(); i++)
{
if (isalnum(preString[i]))
procString += tolower(preString[i]);
}
return procString;
}
// Uses a recursive method to determine if the processed string is a palindrome.
bool is_palindrome(string procString)
{
string temp = process(procString);
int length = temp.length();
string firstChar = temp.substr(0, 1);
string lastChar = temp.substr((length - 1), 1);
if (firstChar == lastChar)
{
temp = temp.substr((0 + 1), (length - 2));
if (temp.length() <= 1) // Base case.
return true;
return is_palindrome(temp); // Recursion.
}
else
return false;
}
// Return a location where text can be added to the non-palindrome to make it a palindrome.
int palindrome_fix_location(string procString)
{
string temp = process(procString);
if (is_palindrome(temp) == false)
{
int palinLoc;
int firstChar = 0, lastChar = temp.length() - 1;
while (firstChar < lastChar)
{
if (temp[firstChar] != temp[lastChar])
{
palinLoc = firstChar;
cout << "Characters to insert at location "
<< palinLoc << " are ";
return palinLoc;
}
}
}
return 0;
}
// Return the text that needs to be added at the "palinLoc" location.
string palindrome_addition(string procString, int palinLoc)
{
string temp = process(procString);
string addedChars;
string finalString;
if (is_palindrome(temp) == false)
{
int firstChar = 0, lastChar = temp.length() - 1;
while (firstChar < lastChar)
{
do {
addedChars += temp[lastChar];
} while (temp[firstChar] != temp[lastChar]);
firstChar++;
lastChar--;
}
finalString = temp.insert(palinLoc, addedChars);
cout << addedChars << endl;
cout << "Final word: " << finalString << endl;
return finalString;
}
else
return finalString;
}
And here's the output I get:
Original line: lappal
Processed line: lappal
Line is palindrome.
-
Original line: lapal
Processed line: lapal
Line is palindrome.
-
Original line: A man, a plan, a canal, Panama!
Processed line: amanaplanacanalpanama
Line is palindrome.
-
Original line: lap
Processed line: lap
Line is NOT a palindrome.
Right there when it says "Line is NOT a palindrome," it's supposed to follow up with something that looks like this:
Characters to insert at location 0 are pa
Final line: palap
It just stops at "Line is NOT a palindrome." Can anyone see where I went wrong with this?
Any help would be greatly appreciated.
your loop here (in palindrome addition) is bugged
do {
addedChars += temp[lastChar];
} while (temp[firstChar] != temp[lastChar]);
it never ends
so you should move either lastchar or firstchar change inside, like this for example
while (firstChar < lastChar)
{
do {
addedChars += temp[lastChar];
lastChar--;
} while (temp[firstChar] != temp[lastChar])
firstChar++;
}
some run here
Original line: lap
Processed line: lap
Line is NOT a palindrome.
start palindrom fix
Characters to insert at location 0 are
start palidrome addition
pa
Final word: palap
Original line: lapin
Processed line: lapin
Line is NOT a palindrome.
start palindrom fix
Characters to insert at location 0 are
start palidrome addition
nipa
Final word: nipalapin
Original line: lapal
Processed line: lapal
Line is palindrome.

Bool value not retuning false in palindrome function, C++

I've sadly read every post pertaining to this topic and can't seem to solve my issue. It's driving me mad.
For some reason on my second or third iteration, if (beg != end) won't return false. It returns false properly if I input, for instance, "bool", but not "blob."
I printed beg and end to make sure things are flowing properly, but still can't find where things are going wrong.
Thank you!!!
#include <iostream>
#include <string>
using namespace std;
bool palindrome_check (string str)
{
string return_str;
int length = str.length()-1;
string beg = str.substr(0, 1);
string end = str.substr(length, 1);
if (beg != end)
{
// cout << beg << " " << end << endl;
return false;
}
else if ((str.length() > 2) && (str.length() != 0))
{
string new_str = str.substr(1, length - 1);
// cout << new_str << endl;
palindrome_check(new_str);
}
return true;
}
int main ()
{
string input;
cout << "Enter a string: ";
cin >> input;
bool is_palindrome = palindrome_check (input);
cout << is_palindrome << endl;
}
You should have used the return values of recursive calls:
string new_str = str.substr(1, length - 1);
return palindrome_check(new_str);
}
return true;
And you should have checked the length of the input string before you extract the first and the last character from it.
If you fix the two mistakes, it should be alright then.

How do I use cin to get a string instead of hard-coding it?

As a homework exercise we were asked to use strchr to count the amount of times a single letter appears in a string of text. It needs to count upper or lower cases as equal. It was suggested we use some sort of bit operations.
I managed to get a working program.
But i would like to make the program more interactive by allowing me to use a cin to input the string instead of typing the string directly into the source code (Which was asked by the exercise).
Is it possible to do this? Or is it not possible in the way i wrote this code.
#include <iostream>
#include <cstring>
using namespace std;
int main(){
const char *C = "This is a necesarry test, needed for testing.";
char target = 'A';
const char *result = C;
const char *result2;
int count = 0;
int j[26] ={0};
//================================================================================================================================================
for(int i = 0; i <= 51; i++){
if (i == 26){
target = target + 6;
}
result2 = strchr(result, target);
while(result2 != NULL){
if (result2 != NULL){
result2 = strchr(result2+1, target);
if (i <= 25){
j[i] = j[i] +1;
}
if(i > 25){
j[i-26] = j[i-26] +1;
}
cout << target << "\t";
}
}
cout << target << endl;
target++;
}
char top = 'a';
for(int o = 0; o<= 25; o++){
cout << "________________________________\n";
cout << "|\t" << top << "\t|\t" << j[o] << "\t|" << endl;
top++;
}
cout << "________________________________\n";
}
Simply use getline() to get a string of characters from the console. Using getline you can also consider the spaces in the user input.
string input;
getline(cin, input);
Now to use this with the strchr functionn you simply have to convert this into a C Type string which can be done as follows :
input.c_str
This returns a C type string so you can put this as an arguement to the function,
You will need
#include <string>