Convert character to lower and upper case in c++ - c++

How can I compare character regardless of its case. Means suppose I enter Z if my if condition shall return true for both Z and z, character can be any alphabet from A-Z or a-z.
Like ABCbabcAABC
If I enter B then it I must get 4 as output because there are 4 B in string.
I am learning C++ on Turbo C++. I am trying to do but now not getting way out.
void main()
{
clrscr();
char str[50],ch;
char str1[50];
int i = 0, l;
cout << "Enter strings: ";
gets(str);
cout << "Enter charcter: ";
cin >> ch;
l = strlen(str);
for(i = 0; i <= l; i++)
{
cout << isupper(str[i]) ? tolower(str[i]) : toupper(str[i]);
}
puts(str);
getch();
}

void main()
{
clrscr();
char str[50],ch;
char str1[50];
int i=0,l;
cout<<"Enter strings: ";
gets(str);
cout<<"Enter charcter: ";
cin>>ch;
l=strlen(str);
int result=0;
for(i=0;i<l;i++)
{
if(tolower(ch)== tolower(str[i]))
{
result++;
}
}
puts(str);
puts(result);
getch();
}

if (tolower(str[i]) == tolower(ch)) {
cout << (isupper(str[i]) ? tolower(str[i]) : toupper(str[i]));
} else {
cout << str[i];
}
40000 is the isupper output. Non zero for an upcase char, zero for lowercase, as written in manual

All you need to do is to play around with the ASCII value.
Check out the code: which explains that you need to convert only those characters whoce ASCII value is between 65(A) to 90(Z).
public class Ques2 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
//ascii A=65 Z=90 a=97
System.out.println("Enter UPPERCASE");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// String input = br.readLine().toLowerCase();
char c;
char[] word=br.readLine().toCharArray();
for(int i :word)
{
if(i>=65 && i<=90){
i=i+32 ;
c=(char) i;
System.out.println(c);
}
else{
c=(char)i;
System.out.println(c);
}
}
}
}

Related

Unexpected Values Being Read Into Memory with getline() - C++

I wrote this program for an intro to C++ course. My issue is that unexpected values are being stored in memory. I assume it has to do with input.getline() or the way certain characters are stored, but I don't know enough about what is happening "under the hood" to fix it.
Specifically, certain characters like apostrophes and quotation marks appear to not read as their hex ASCII counterparts.
I'm pretty certain the issue lies in the lines
input.getline(raw_paragraph, MAX_PARAGRAPH_CHARS);
charCount = strlen(raw_paragraph);
Below I've included the complete code, a screenshot of the Memory from Visual Studio 2022, the test case, and the program output .
Thank you in advance!
#pragma warning(disable : 4996) //DEV
/**************************************************************************************
Header Content
**************************************************************************************/
// Includes and namespaces ------------------------------------------------------------
#include <cstdlib> // Defines functions such as exit().
#include <cstring> // Defines functions such as strcmp, etc.
#include <fstream> // Supports file I/O
#include <iostream> // Supports terminal I/O
using namespace std;
// Constants Declared -----------------------------------------------------------------
// Maximum allowable space for input / Defines space for memory allocation
const int MAX_WORD_CHARS = 50; // Longest word = 50 chars
const int MAX_WORDS = 1000; // Longest paragraph = 1000 words
const int MAX_PARAGRAPH_CHARS = 50000; // 50 * 1000
// "to be" Semantics
const char TO[] = "to";
const char BE[] = "be";
const int NUM_TO_BE_VERBS = 5; // Qty of "to be verbs below
const char TO_BE_VERBS[NUM_TO_BE_VERBS][MAX_WORD_CHARS] =
{ "am", "are", "is", "was", "were" };
// Conjunctions
const int NUM_CONJUNCTIONS = 7; // Qty objects in CONJUNCTIONS below.
const char CONJUNCTIONS[NUM_CONJUNCTIONS][MAX_WORD_CHARS] =
{ "for", "and", "nor", "but", "or", "yet", "so" };
// Punctuation
const int NUM_PUNCTUATIONS = 4;
const char PUNCTUATIONS[NUM_PUNCTUATIONS] = { '.', ',', '?', '!' };
// Functions Declared -----------------------------------------------------------------
int countComplex(char a[][MAX_WORD_CHARS], int b);
int countSentences(char a[], int b);
int count_to_be_verbs(char a[][MAX_WORD_CHARS], int wc);
void init_array(char* a);
void modify_tokens(char a[][MAX_WORD_CHARS], int wc);
int tokenizeParagraph(char p[], char tp[][MAX_WORD_CHARS]);
/**************************************************************************************
Begin Main
**************************************************************************************/
int main()
{
// Format Output
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(1);
// Create input space for user's file request
char filename[256]; // Stores the user defined filename containing plaintext
init_array(filename);
char raw_paragraph[MAX_PARAGRAPH_CHARS]; // Stores plaintext from filename
init_array(raw_paragraph);
// Declare Variables
int charCount = 0; // Number of chars contained in input file except eof.
int complex_count; // Number of complex sentences
int sentenceCount = 0; // Total number of sentences in input
int simpleSent = 0; // Number of simple sentences in input
int to_be_count; // Number of instances of "to be" verbs in input.
int wordCount = 0; // Number of words in input
double averageWordsPerSentence;
// Asks the user for the name of an input file which contains a paragraph
cout << "Enter a filename: ";
cin.getline(filename, 256);
// Try to load the file in filename:
ifstream input;
input.open(filename);
// If file does not exist, cout error then exit(1)
if (input.fail())
{
cout << "Input file " << filename << " does not exist." << endl;
cout << "Thank you for using the English Analyzer." << endl;
exit(1);
}
// If file is empty, cout "Input file _____ is empty." Then exit(1)
char c;
input.get(c);
if (input.eof())
{
cout << "File " << filename << " is empty." << endl;
cout << "Thank you for using the English Analyzer." << endl;
exit(1);
}
else
input.putback(c);
// Store plaintext from file to raw_paragraph
input.getline(raw_paragraph, MAX_PARAGRAPH_CHARS);
// Close ifstream input, will not need it again.
input.close();
// Allocate memory for the output of tokenizeParagraph
char tkn_para[MAX_WORDS][MAX_WORD_CHARS];
// Count chars
charCount = strlen(raw_paragraph);
// Tokenize paragraph, count words
wordCount = tokenizeParagraph(raw_paragraph, tkn_para);
// Count Sentences
sentenceCount = countSentences(raw_paragraph, charCount);
// Average words per sentence
averageWordsPerSentence = double(wordCount) / double(sentenceCount);
// Count Complex Sentences
complex_count = countComplex(tkn_para, wordCount);
// Calculate Simple Sentences
simpleSent = sentenceCount - complex_count;
// Count "to be" verbs
modify_tokens(tkn_para, wordCount);
to_be_count = count_to_be_verbs(tkn_para, wordCount);
// Cout results
cout << "Number of Characters: " << charCount << endl;
cout << "Number of words: " << wordCount << endl;
cout << "Number of sentences: " << sentenceCount << endl;
cout << "Average number words in a sentence: " << averageWordsPerSentence << endl;
cout << "Number of simple sentences: " << simpleSent << endl;
cout << "Number of \"to be\" verbs: " << to_be_count << endl;
}
/**************************************************************************************
Function Definitions
**************************************************************************************/
int countComplex(char a[][MAX_WORD_CHARS], int b)
{
// counter will keep the number of complex sentences found.
int counter = 0;
// For each word in tkn_para,
for (int i = 0; i < b; i++)
{
// If a comma is at the end of tkn_m,
int s = strlen(a[i]) -1;
if (a[i][s] == ',')
{
// For each word in CONJUNCTIONS
for (int x = 0; x < NUM_CONJUNCTIONS; x++)
{
// If the words match,
if (strcmp(a[i + 1], CONJUNCTIONS[x]) == 0)
{
// Increment counter
counter++;
// If a word from a has already been matched, there
// is no reason to try to compare it to more items
// from CONJUNCTIONS. Therefore,
break;
}
}
}
}
// After all iteration has been completed:
return(counter);
}
int countSentences(char a[], int b)
{
int counter = 0;
// For each char in a[]
for (int i = 0; i < b; i++)
{
// If a[i] is an end of sentence punctuation,
if (a[i] == '.' || a[i] == '?' || a[i] == '!')
// Increment counter
counter++;
}
return counter;
}
int count_to_be_verbs(char a[][MAX_WORD_CHARS], int wc)
{
int counter = 0;
// For each word in a:
for (int i = 0; i < wc; i++)
// For each word in TO_BE_VERBS:
for (int y = 0; y < NUM_TO_BE_VERBS; y++)
{
// If words match:
if (strcmp(a[i], TO_BE_VERBS[y]) == 0)
counter++;
}
// For loop checks for "to" token followed by "be"
for (int i = 0; i < wc; i++)
if (strcmp(a[i], TO) == 0 && strcmp(a[i + 1], BE) == 0)
counter++;
return(counter);
}
void init_array(char* a)
{
// For every char in a:
for (int i = 0; i < strlen(a); i++)
// Set the value of a[i] to NULL
a[i] = NULL;
}
void modify_tokens(char a[][MAX_WORD_CHARS], int wc)
{
// For each word in a:
for (int i = 0; i < wc; i++)
{
// Does the computation once instead of 4 times below.
int s = strlen(a[i]) -1;
// Converts first char if uppercase, into lowercase
if (int('#') < a[i][0] && a[i][0] < int('['))
a[i][0] = a[i][0] + 32;
// Convert last char, if punctuation mark, into NULL
if (a[i][s] == ',' || a[i][s] == '!' || a[i][s] == '?' || a[i][s] == '.')
a[i][s] = NULL;
}
}
int tokenizeParagraph(char p[], char tp[][MAX_WORD_CHARS])
{
int i = 0;
char* cPtr;
cPtr = strtok(p, " \n\t");
while (cPtr != NULL)
{
strcpy(tp[i], cPtr);
i++;
cPtr = strtok(NULL, " \n\t");
}
return(i);
}
Turns out that the issue has to do with copying the test case into MS Word or another like application. There are character equivalents to apostrophes and quotation marks that "lean" left or right. Those characters are actually distinct and are responsible for the memory values I've been encountering. It suggests to me that a future iteration of the code would have to parse the raw input for those types of characters and replace them.

write a code for checking valid email address,

i was writing a code on code blocks for checking a valid email address by checking following conditions:
1.must have at least one uppercase.
2.should have characters above 8 and less than 50
3.should have # sign
i have used 3 while loops for checking individual condition , but after entering the email address the program gets stopped . here is my code ,does anyone know what is the problem?
enter code here
#include<iostream>
using namespace std;
#include<stdio.h>
#include<conio.h>
void check_mail()
{
int i = 0;
char email[25];
int measure = 0;
cout<<" \n \n \n enter an email address ::";
gets(email);
while(email[i] != '\0')//for checking uppercsae //
{
if( (int)email[i] >= 65 && (int)email[i] <= 90)
{
measure = 1;
}
if( measure != 1)
{
cout<<"\n there is no uppercase letter in the email address ";
break;
}
}
while(email[i] != '\0') //checking # sign//
{
if((int)email[i] == 64)
{
cout<<" \n found the # character at :: "<<i<<endl;
}
}
int counter = 0;
while(email[i] != '\0')
{
counter = counter +1 ;
}
if(counter >=8 && counter <=50)
{
cout<< "\n valid number of characters are present in the mail :: ";
}
else if(counter <8)
{
cout<<" \n number of characters are less than 8 ";
}
else if(counter >=51 )
{
cout<<"\n the elements are greater than 50 ";
}
else
{
cout<<"\n enter a valid email address::";
}
}
int main()
{
cout<<" \n \n enter a email address ";
check_mail();
return 0;
}
This code below is a working and a way better implementation of your code:
#include <iostream>
#include <string>
bool check_mail(const std::string email)
{
if (email.size() < 8 || email.size() > 50) return false;
int upper_letters = 0;
for (int i = 0; i < email.size(); i++)
{
if (std::isupper(email[i])) upper_letters++;
if (email[i] == '#')
{
if (i < 8) return false;
else if (upper_letters == 0) return false;
return true;
}
}
return false;
}
int main()
{
std::cout << " \n \n Enter an email address ";
std::string email; std::cin >> email;
std::cout << check_mail(email) << std::endl;
return 0;
}
If you need to know what exactly caused the email to get rejected, you can do the following:
#include <iostream>
#include <string>
enum email_states { correct, under_char, over_char, no_upper, no_at_the_rate };
email_states check_mail(const std::string email)
{
if (email.size() < 8) return email_states::under_char;
else if (email.size() > 5) return email_states::over_char;
int upper_letters = 0;
for (int i = 0; i < email.size(); i++)
{
if (std::isupper(email[i])) upper_letters++;
if (email[i] == '#')
{
if (i < 8) return email_states::under_char;
else if (upper_letters == 0) return email_states::no_upper;
return email_states::correct;
}
}
return email_states::no_at_the_rate;
}
int main()
{
std::cout << " \n \n Enter an email address ";
std::string email; std::cin >> email;
std::cout << check_mail(email) << std::endl;
return 0;
}
For the 2'nd code, if the output is:
0 - correct
1 - under_char
2 - over_char
3 - no_upper
4 - no_at_the_rate
Also, using namespace std is considered as a bad practice. For more info on this look up to why is "using namespace std" considered as a bad practice.
You could consider using std::string and utilizing the standard library:
#include <iostream>
#include <string>
constexpr int kMinEmailCharacters = 8;
constexpr int kMaxEmailCharacters = 50;
constexpr char kAtSign = '#';
bool IsValidEmail(const std::string &email) {
auto email_length = email.length();
auto contains_uppercase = std::count_if(email.begin(), email.end(), isupper);
auto contains_at_sign = email.find(kAtSign) != std::string::npos;
return email_length > kMinEmailCharacters &&
email_length < kMaxEmailCharacters && contains_uppercase &&
contains_at_sign;
}
int main() {
std::cout << "Enter email: ";
std::string user_email;
std::cin >> user_email;
auto valid_email = IsValidEmail(user_email);
std::cout << "Valid email: " << (valid_email ? "true" : "false") << '\n';
return 0;
}
Example Usage 1:
Enter email: tejaspatil#mail.com
Valid email: false
Example Usage 2:
Enter email: Tejaspatil#mail.com
Valid email: true
There are some logic errors in the code:
in the first loop you print "there is no uppercase letter in the email address" when the first character is not an uppercase letter. You need to check all letters before you know if there was an uppercase
after the first loop, i is already at the end of the string, the next loop will not have a single iteration.
Further
use std::string
conio.h is windows only. You don't need it when you can use std::cin.
while(email[i] != '\0') is error-prone (you need to corrceclty manage the index, which your code fails to do). Use a range based loop instead
try to avoid magic numbers.
don't use C-style casts
in particular there is no need to cast the characters to int. You can compare directly to 'A' and 'Z'.
after you checked if the size of the input is <8 or >=8 && <=50 or >51 there is no other case, the else is superfluous.
Your code with this fixes:
#include<iostream>
using namespace std;
void check_mail()
{
int i = 0;
std::string email;
int measure = 0;
cout<<" \n \n \n enter an email address ::";
//gets(email);
std::cin >> email;
for (char c : email) {
if( c >= 'A' && c <= 'Z') { measure = 1; }
}
if( measure != 1) {
cout<<"\n there is no uppercase letter in the email address ";
//break;
}
for (char c : email) {
if(c == '#') {
cout<<" \n found the # character at :: "<<i<<endl;
}
}
int counter = email.size();
if(counter >=8 && counter <=50) {
cout<< "\n valid number of characters are present in the mail :: ";
}
else if(counter <8) {
cout<<" \n number of characters are less than 8 ";
}
else if(counter >=51 ) {
cout<<"\n the elements are greater than 50 ";
}
}
int main()
{
cout<<" \n \n enter a email address ";
check_mail();
return 0;
}
Produces expected output for input "Foo#bar.com":
enter a email address
enter an email address ::
found the # character at :: 0
valid number of characters are present in the mail ::
I suppose for the last output you also wanted to add email.size() to the output.
You consider using Regex for check email:
// C++ program for the above approach
#include <iostream>
#include <regex>
using namespace std;
// Function to check the email id
// is valid or not
bool isValid(const string& email)
{
// Regular expression definition
const regex pattern(
"(\\w+)(\\.|_)?(\\w*)#(\\w+)(\\.(\\w+))+");
// Match the string pattern
// with regular expression
return regex_match(email, pattern);
}
// Driver Code
int main()
{
// Given string email
string email = "mail#gmail.com";
// Function Call
bool ans = isValid(email);
// Print the result
if (ans) {
cout << email << " : "
<< "valid" << endl;
}
else {
cout << email << " : "
<< "invalid" << endl;
}
}

When I input a number in char type, why i can't get a whole number?

I input a number in char type variable. like 12 or 22. but, console show me a 1 or 2.
How i get a whole number 12 ,22 in console?
#include <iostream>
int main()
{
using namespace std;
char a = 0;
cin >> a;
cout << a << endl;
return 0;
}
Here is console result.
12
1
C:\Users\kdwyh\source\repos\MyFirstProject\Debug\MyFirstProject.exe(프로세스 18464개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
The reason I don't use int, string and something is because I want to get both number and Character in one variable.
So I want to see the results of combined numbers and character at the same time.
in that process i can't get a whole number.
#include <iostream>
using namespace std;
int index = 0;
constexpr int pagenum = 10;
void chapterlist(void);
void nextlist(void);
void beforelist(void);
void movechapter(char a);
int main(void)
{
char userin = 0;
bool toggle = 0;
cout << "결과를 볼 챕터를 고르시오." << endl;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cin >> userin;
if (userin == 'n')
{
backflash:
while(toggle == 0)
{
nextlist();
cin >> userin;
if (userin == 'b')
{
toggle = 1;
goto backflash;
}
else if (userin == 'n')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
while(toggle == 1)
{
beforelist();
cin >> userin;
if (userin == 'n')
{
toggle = 0;
goto backflash;
}
else if (userin == 'b')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
}
else
{
system("cls");
movechapter(userin);
}
return 0;
}
void chapterlist(void)
{
int x = 0;
for (x = index + 1; x <= index + 10; x++)
cout << "Chapter." << x << endl;
}
void nextlist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index + pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void beforelist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index - pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void movechapter(char a)
{
cout << "선택한 Chapter." << a << "의 결과입니다." << endl;
}
In movechapter(), console show me a is 1 or 2, not 12, 22.
First, you have to understand what achar type is.
Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which is a one-byte character. Other types are also provided for wider characters.
To simplify that, char can only hold one character.
Where as with your code, "12" is actually 2 separate characters, '1' and '2', and that's the reason it would not work.
Instead of declaring a as a char type, you could declare it as an int type, which is a type designed to hold numbers. So you would have:
int a = 0;
However, do note that int often has a maximum value of 2^31.
Or you could use std::string to store character strings. However, do note that if you wish to do any calculations to your string type, you would need to convert them to a number type first:
int myInt = std::stoi(myString);
Edit:
So I have re-checked your code after your update, there is nothing wrong with using std::string in your case. You can still check if user have input n or b by:
if (userin == "n")
Note that you would use double quotation mark, or "letter", around the content that you want to check.
On the other hand, you could use:
if(std::all_of(userin .begin(), userin.end(), ::isdigit))
To check if user have input a number.
Although char is just a number, it's presumed to mean "single character" here for input. Fix this by asking for something else:
int a = 0;
You can always cast that to char as necessary, testing, of course, for overflow.
You should be reading characters into a string, and then converting that string into an int. It would also probably make more sense to use something like getline() to read input, rather than cin >> a.
#include <string>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
int main() {
std::string input_string;
/* note that there is no function that will convert an int string
to a char, only to an int. You can cast this to a char if needed,
or bounds check like I do */
int value;
while(1) {
getline(std::cin, input_string);
/* std::stoi throws std::invalid_argument when given a string
that doesn't start with a number */
try {
value = std::stoi(input_string);
} catch (std::invalid_argument) {
printf("Invalid number!\n");
continue;
}
/* You wanted a char, the max value of a `char` is 255. If
you are happy for any value, this check can be removed */
if (value > 255) {
printf("Too big, input a number between 0-255\n");
continue;
}
break;
}
printf("Number is %hhu\n", value);
}

Need assistance with Vigenere Cipher program

I am helping a friend create a program that encrypts/decrypts messages using the "Vigenere Cipher." I was unsure what this was, so I did my own research and think I have it figured out.
My code runs fine from a syntax perspective. But, from a logic perspective, it does not work. From my understanding, when I encrypt a message with a key, if I decrypt the encrypted message using the same key, it should give me the original message. Mine does not. From my debugging attempts, I think the issue lies somewhere in my decrypting algorithm, but could be entirely wrong.
Here is my code:
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
using namespace std;
int main(){
//initializing functions to be used
int giveInfo();
void encrypt(string message, string key);
void decrypt(string message, string key);
void newKey(string key);
string keyInput();
string messageInput();
int userChoice();
giveInfo();
//loop so that the user can decrypt/encrypt multiple messages
int counter = 1;
int userCounter;
while (counter == 1){
int choice = userChoice();
if(choice == 1){
string inputMessage = messageInput();
string inputKey = keyInput();
encrypt(inputMessage, inputKey);
}
else{
string inputMessage = messageInput();
string inputKey = keyInput();
decrypt(inputMessage, inputKey);
}
cout << "Would you like to decrypt/encrypt another message? (1 = yes, 2 = no)";
cin >> userCounter;
counter = userCounter;
system("CLS");
}
return 0;
}
//gives the user a basic description of cypher and what they need to input
int giveInfo(){
cout << "\nThe Vigenere Cypher is a polyalphabetic encryption/decryption method. It utilizes a 'key' (provided by the user, \nany word of any length) to determine which letters will replace others. This means in order to decrypt a message,\n one will need the key the person who encrypted the messafe used, ensuring a secure encryption. To use this program, \nyou will need to enter your message (this will be converted into all capitol letters) and a key which you would like to use. Do not use any spaces in your message.\n\n\n";
return 0;
}
string messageInput(){
//message place holder
string userMessage;
//asking for message
cout << "What is the message you would like to encrypt/decrypt?\n";
cin >> userMessage;
return userMessage;
}
string keyInput(){
//key place holder
string userKey;
//asking for key
cout << "What is the key you would like to use?\n";
cin >> userKey;
return userKey;
}
void decrypt(string message, string key){
//generating new key to match message length
int x = message.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == message.size())
break;
key.push_back(key[i]);
}
string orig_text;
for (int i = 0 ; i < message.size(); i++)
{
// converting in range 0-25
int x = (message[i] - key[i] + 26) %26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
}
cout << "\n\nEncrypted Code: " + message+ "\n";
cout << "Key: " + key+ "\n";
cout << "Decrypted message: ";
cout << orig_text + "\n";
}
//takes user input (message to be encyrpted and key to be used) as arguments and returns encrypted
void encrypt(string message, string key){
string cipher_text;
//generating new key to match message length
int x = message.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == message.size())
break;
key.push_back(key[i]);
}
for (int i = 0; i < message.size(); i++)
{
// converting in range 0-25
int x = (message[i] + key[i]) %26;
// convert into alphabets(ASCII)
x += 'A';
cipher_text.push_back(x);
}
cout << "\n\nOriginal message: " + message+ "\n";
cout << "Key: " + key+ "\n";
cout << "Encrypted message: ";
cout << cipher_text + "\n";
}
int userChoice(){
int choice;
cout << "Would you like to encrypt a message or decrypt a message? (1 =
encrypt, 2 = decrypt)\n";
cin >> choice;
return choice;
}
Any help?
Since your intention is to use an alphabet with a length of 26, you need to make sure your input is properly normalized prior to performing any encryption/decryption operations.
I would suggest ensuring that user input for the message & key is converted to upper case.
e.g. utilizing toupper: for(char &c : inputMessage) c = toupper(c)
Could you provide your input & output? Your code works just fine.
Original Message: ATTACKATDAWN
Key: LEMONLEMONLE
Encrypted Message: LXFOPVEFRNHR
Encrypted Code: LXFOPVEFRNHR
Key: LEMONLEMONLE
Decrypted Message: ATTACKATDAWN

Validating User String User Input

So I've been trying to create this program that will take up to 12 digits from the user using string and string classes. The issue I'm having is:
Ignoring the (-) sign.
Ignoring the decimal point.
Giving an error when more than 12 digits are entered.
Only accepting digits (i.e no letters)
So far this is what I have:
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
using namespace std;
bool test(char [] , int);
int main()
{
const int SIZE= 13;
char number[SIZE];
int count;
cout<< "Please enter a number up to "<< (SIZE-1) <<" digits long." << endl;
cout<< "The number may be positive or negative" << endl;
cout<< "and may include fractions (up to two decimal positions)" << endl;
cout<< "Sign and decimal dot(.) are not included in the digit count:"<< "\t";
cin.getline (number, SIZE);
if (test(number, SIZE))
{
while (number[count]!='\0')
{
cout<< "The currency value is: \t $";
cout<< setprecision(2) << number[count];
count++;
}
}
else
{
cout << "Invalid number: contains non-numeric digits.";
}
return 0;
}
bool test(char testNum[], int size)
{
int count;
for (count = 0; count< size; count++)
{
if(!isdigit(testNum[count]))
return false;
}
return true;
}
Any help is very much appreciated, but the most important to me at the moment is the 4th point. No matter what the input is, the output is "Invalid number:...." and I'm not sure why that is.
Your test function always test 13 chars even if the input is shorter.
Instead pass a string and use the range based for-loop so that you only test the valid chars - something like:
bool test(string testNum)
{
for (auto c : testNum)
{
if(!isdigit(c))
return false;
}
return true;
}
Further you should change your main-loop (where you print the value) as well, i.e. use string instead of char-array.
BTW - notice that this will only check for digits. Your description of the valid input format will require a more complex test-function.
For instance to check for sign you could add:
bool test(string testNum)
{
bool signAllowed = true;
for (auto c : testNum)
{
if (c == '-')
{
if (!signAllowed) return false;
}
else
{
if(!isdigit(c)) return false;
}
// Sign not allowed any more
signAllowed = false;
}
return true;
}
But you still need more code to check for the dot (.)
If you don't want to use a range-based for loop, you can do:
bool test(string testNum)
{
for (int i = 0; i < testNum.size(); i++)
{
if (testNum[i] == '-')
{
// Sign is only allowed as first char
if (i != 0) return false;
}
else
{
if(!isdigit(testNum[i])) return false;
}
}
return true;
}