multiple branch if else statements - if-statement

I'm trying to identify a single character as a letter either upper case or lowercase. I'm having trouble with the logic of the if else statement. any help would be really appreciated. When it runs it will now print whether it is upper or lower case.
String x = "";
if (Character.isLetter(x)) {
System.out.println(x + " is a letter.");
}
else if (Character.isUpperCase(x)) {
System.out.println(x + " is upper case.");
}
else if (Character.isLowerCase(x)) {
System.out.println(x + " is lower case.");
}

Try this...
if (Character.isLetter(x)) {
System.out.println(x + " is a letter.");
if (Character.isUpperCase(x)) {
System.out.println(x + " is upper case.");
}
else if (Character.isLowerCase(x)) {
System.out.println(x + " is lower case.");
}
}

Related

Logic error when getting output from encrypting string program.

I have made a program that takes a string into a class EncryptedString then encrypts said string removing anything that is not a space or a lower or uppercase letter. Everything seems to be working fine until I enter a string with something like 496496#####!#!!!4 then it deletes some, and keeps others. I have some examples of what is supposed to be output.
Input: Hello World!
Expected Decrypted: Hello World
Expected Encrypted: Ifmmp Xpsme
Output Decrypted: Hello World
Output Encrypted: Ifmmp Xpsme
Hello World works, just fine and deletes the !
However when I try to do "A apple ran away in autumn z!!14? I get this
Input: A apple ran away in autumn z!!14?
Expected Decrypted: A apple ran away in autumn z
Expected Encrypted: B bqqmf sbo bxbz jo bvuvno a
Output Decrypted: A apple ran away in autumn z 3
Output Encrypted: B bqqmf sbo bxbz jo bvuvno a!4
And here is one more example.
Input: Emily Dickinson1152163!!!#####!!!
Expected Decrypted: Emily Dickinson
Expected Encrypted: Fnjmz Ejeljotpo
Output Decrypted: Emily Dickinson015 ??
Output Encrypted: Fnjmz Ejdljotpo126!!##!!
I thought it may be that when I am iterating the code over decrypt.length() and enCry.length() it's going over the elements? However, I felt like it wasn't that as it's able to delete other numbers and symbols just fine but for some reason, some are staying. Is there something wrong with my code below during my iterations that can cause this?
//This function takes the phrase,word or sentence and encrypts it, removing any illegal characters aside from ' ' and then proceeds to decrypt it then output them to the get functions.
void EncryptedString::set(string str)
{
char chBase = 'A';
string enCry = str;
for (int i = 0; i < enCry.length(); i++)
{
char ch = enCry[i];
if (enCry[i] < chBase && enCry[i] != ' ')
{
enCry.erase(enCry.begin() + i);
}
else if (enCry[i] > chBase + 25 && enCry[i] < tolower(chBase) && enCry[i] != ' ')
{
enCry.erase(enCry.begin() + i);
}
else if (enCry[i] > tolower(chBase + 25) && enCry[i] != ' ')
{
enCry.erase(enCry.begin() + i);
}
else
{
if (enCry[i] == chBase + 25)
{
enCry[i] = 'A';
}
else if (enCry[i] == tolower(chBase) + 25)
{
enCry[i] = 'a';
}
else if (enCry[i] == ' ')
{
enCry[i] = ' ';
}
else
{
enCry[i] = ch + 1;
}
}
}
EncryptedString::encryption = enCry;
string decrypt = enCry;
for (int i = 0; i < decrypt.length(); i++)
{
char ch = decrypt[i];
if (decrypt[i] == 'A')
{
decrypt[i] = 'Z';
}
else if (decrypt[i] == 'a')
{
decrypt[i] = 'z';
}
else if (decrypt[i] == ' ')
{
decrypt[i] = ' ';
}
else
{
decrypt[i] = ch - 1;
}
}
decrypted = decrypt;
}
//This function outputs the decryption after the phrase was encrypted.
const string EncryptedString::get()
{
return decrypted;
}
//This function outputs the encryption of the phrase.
const string EncryptedString::getEncrypted()
{
return EncryptedString::encryption;
}
As some more information here is what is in main.cpp where I am using these functions. I thought maybe it was because I was setting it twice in test2 but I tested test1 by adding numbers to hello world and that output just kept some of the numbers with it. If you need to see that example I will provide.
#include "EncryptedString.h"
#include <windows.h>
int main()
{
cout << "TEST 1" << endl << endl;
EncryptedString test1("Hello World!");
cout << test1.get();
cout << endl << endl;
cout << test1.getEncrypted();
cout << endl << endl << "TEST 2" << endl << endl;
EncryptedString test2;
test2.set("A apple ran away in autumn z!!14?");
cout << endl << endl;
cout << test2.get();
cout << endl << endl;
cout << test2.getEncrypted();
cout << endl << endl;
test2.set("Emily Dickson1152163!!!#####!!!");
cout << test2.get() << endl << endl << test2.getEncrypted();
//being used for me to see the output.
Sleep(15000);
}
If someone can see where I went wrong or if maybe something is off with my iteration I'd be grateful. Thank anyone for reading all of this as I know it's probably a lot and thank you for any help that you can give me. Also would this be considered a logic error or structure error? I believe logic but I could be wrong and I would like to know so I don't make that mistake in the future when asking for help.

Why is the line end character not included in the char*?

Function TrimRight takes a line and removes all spaces at the end.
void TrimRight(char *s) // input "somestring " (3 spaces at the end)
{
// Here s == "somestring \0" and strlen(s) == 14
int last = strlen(s) - 2;
std::cout << "Last1: " << s[last] << std::endl; // Last == ' '
while (s[last] == ' ')
{
--last;
}
std::cout << "Last2: " << s[last] << std::endl; // Last == 'g'
s[last + 1] = '\0';
// Here s == "somestring" and strlen(s) == 10
}
Questions is why s!= "somestring/0" after TrimRight(s)?
I'm using MVS 2017. Thanks.
You thought after TrimRight(s), s become something\0.
But in TrimRight(s) function, while loop just passed from last index.
Pass mean it didn't delete whitespace and \0.
so s is not something\0. It is something\0 \0 because of "just pass".

Why does starting value affect outcome of Seeded Random?

Trying to figure out why the starting value affects the seeded random in this code. I would expect for it to find the match at the same location for 12 character or more match no matter of the starting value for the seed, but it seems as though I am getting different results depending on the starting value of the seed which to me makes no sense. Anyone who why I am getting these results as shown from 0, 1, 2, and 3 for starting values when all 4 should flag the same values as a match to 12 more more characters.
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **0** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
**Greater or Equal to = 12 ===== 923425024**
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **1** thru 1000000000
WARNING - Program Running Please Wait...
**Greater or Equal to = 12 ===== 204715678**
25% Complete
**Greater or Equal to = 12 ===== 346933630**
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **2** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Poor Key Finder
Search for 12 or more matches
Searching through Key Values of **3** thru 1000000000
WARNING - Program Running Please Wait...
25% Complete
50% Complete
75% Complete
100% Complete
Completed = 1000000000
Press any key to continue . . .
Code:
#include <iostream>
#include <string>
int delay;
long long int counter1 = 0; // Add LL beyond 9 digits
long long int endcount = 0; // while loop end counter
long long int seed1 = 0;
int match2 = 0;
int ST = 0;
int flag = 0;
float progress = 0;
int step1 = 0;
int step2 = 0;
int step3 = 0;
int main()
{
system("color b0");
std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n";
std::cout << " Poor Key Finder Version 1.0\n";
std::cout << " Build 01/30/2016\n";
std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n";
std::cout << " Enter Starting Key Value\n";
std::cin >> counter1;
std::cout << " Enter Ending Key Value\n";
std::cin >> endcount;
std::cout << " Enter Duplicate Character Counter Value\n";
std::cin >> flag;
system("cls");
std::string str =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()_-+=?<>:\\/~.,;";
std::string str2=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!##$%^&*()_-+=?<>:\\/~.,;";
system("#echo. Started on %date% at %time%>>LogKey.txt");
system("color f0");
std::cout << "Poor Key Finder - Search for " << flag
<< " or more matches \n";
std::cout << "Searching through Key Values of " << counter1 << " thru "<<endcount<<"\n\ n";
std::cout << " WARNING - Program Running Please Wait...\n\n";
while (counter1 <= endcount)
{
seed1 = counter1;
srand(seed1);
random_shuffle(str.begin(), str.end()); // Shuffle the string
ST = 0;
match2 = 0;
progress = ((100 * counter1) / endcount);
if (progress == 25)
{
step1++;
if (step1 == 1)
{
std::cout << "25% Complete\n";
}
else
{
}
}
else if (progress == 50)
{
step2++;
if (step2 == 1)
{
std::cout << "50% Complete\n";
}
else
{
}
}
else if (progress == 75)
{
step3++;
if (step3 == 1)
{
std::cout << "75% Complete\n";
}
else
{
}
}
else if (endcount == counter1)
{
std::cout << "100% Complete\n";
}
else
{
}
while (ST <= 85)
{
if (str[ST] == str2[ST])
{
match2++;
}
else
{
}
ST++;
}
if (match2 >= flag)
{
std::cout << "Greater or Equal to = " << flag << " ===== " << seed1
<< "\n";
}
else
{
}
counter1++;
}
std::cout << "Completed = " << endcount << "\n\n\n";
system("#echo. Ended on %date% at %time%>>LogKey.txt");
system("pause");
return 0;
}
I now understand what you are asking! The problem is because you shuffle str on each iteration without resetting it to its initial value each time, so it accumulates randomness from the previous iterations' shuffles.
In other words, you have two "seeds" -- one in the counter which you set each iteration using srand and one you do NOT reset, contained in str's shuffled character order.
To keep each iteration consistent, you need to reset str to the same base value before each shuffle.

Modulo in a conditional expression

I'm very new to programming and am starting out with Bjourne's book: Programming principles and practice c++ 2nd edition. Exercise 8 chapter 3 he asks for:
"Write a program to test an integer value to determine if it is odd or even...Hint: See the remainder (modulo)operator in ยง3.4."
I can do that with something like:
int main() {
int n;
cout << "Enter an integer: ";
cin >> n;
if ( n%2 == 0) {
cout << n << " is even.";
}
else {
cout << n << " is odd.";
}
return 0;
}
But he gives in his website his own solution:
int main()
{
int val = 0;
cout << "Please enter an integer: ";
cin >> val;;
if (!cin) error("something went bad with the read");
string res = "even";
if (val%2) res = "odd";
cout << "The value " << val << " is an " << res << " number\n";
keep_window_open();
}
catch (runtime_error e) {
cout << e.what() << '\n';
keep_window_open("~");
}
/*
Note the technique of picking a default value for the result ("even") and changing it only
if needed.
The alternative would be to use a conditional expression and write
string res = (val%2) ? "even" : "odd";
What is
string res = "even";
if (val%2) res = "odd";
and
string res = (val%2) ? "even" : "odd";
actually doing? I haven't seen him explaining those before in the book. Also, the last code, It gives me "odd" result when I type an even value and gives an "even " result when I type and odd one. what is going on? Sorry for the long post, hope I could explain what I need...
The ? : is the ternary operator.
if (val%2) res = "odd";
is just a rather terse version of
if (val%2) {
res = "odd";
}
And note that if(...) actually doesn't care whether the value is "true" or "false." It just checks for zero or nonzero. So it's equivalent to
if( val%2 != 0)
The second command line : string res = (val%2) ? "even" : "odd"; similary is a short way for writing:
string res;
if(val%2 != 0){
res = "even";
}
else{
res = "odd";
}
The syntax for those kind of commands is condition ? value_if_true : value_if_false
Adding to the previous answers, you have to note the boolean (or "true" values) are 0s and 1s, (0 being false and 1 being true in boolean algebra)
So, when
string res = (val % 2) ? "even" : "odd";
Note that when you give and odd value it will always return number 1 which is "true", and viceversa for even numbers.
You would have to turn those around for the program to work.
He just instead of writing multiple brackets, does not use them at all
string res = "even"; //default value
if (val%2) res = "odd"; //in case it is odd, value changes
//output or threat in some way value.
instead
string res = (val%2) ? "even" : "odd";
Simply a short way of writing the same if/else you wrote before.

Using CheckSum with C++ for 13 Digit ISBN

I am trying to calculate the final digit of a 13 digit ISBN using the first 12 digits using C++. I feel like my code should be correct but I have a feeling the formula I'm using may be wrong.
The formula is:
10 - (d0 + d1 * 3 + d2 + d3 * 3 + d4 + d5 * 3 + d6 + d7 * 3 + d8 + d9 * 3 + d10 + d11 * 3) % 10
Here's what I have:
#include <cstring>
#include <iostream>
int main() {
int weightedSum = 0;
int checksum = 0;
int i; //for loop decrement
int mul = 3;
const int LENGTH = 12;
char ISBNinput[LENGTH];
std::cout << "Enter first 12 digits of ISBN: "; //ask user for input
std::cin >> ISBNinput; //stores input into ISBNinput
std::cout << std::endl;
for (i = 0; i < strlen(ISBNinput); i++) {
weightedSum += (ISBNinput[i] % 12) * mul;
if (mul == 3) {
mul = 1;
} else {
mul = 3;
}
}//close for loop
checksum = weightedSum % 10; //calculates checksum from weightedSum
std::cout << checksum << std::endl; //prints checksum with new line for format
return 0;
}
For example:
978007063546 should return 3
and
978032133487 should return 9
Thank you for any help.
Here's how I go about this.
First, let's decide how we're going to test this. I'll assume that we've written the function, and that it gives the correct output. So I pick up a couple of books off my desk, and test that it works for them:
#include <iostream>
int main()
{
std::cout << "Book 1 - expect 3, got " << checksum("978032114653") << std::endl;
std::cout << "Book 2 - expect 0, got " << checksum("978020163361") << std::endl;
}
Of course, when we try to compile that, we get an error. So create the function, before main():
char checksum(const char *s)
{
return '1';
}
Now it compiles, but the result is always 1, but now we can start to fill in the body. Let's start with some smaller examples, that we can calculate by hand; add these at the beginning of main():
std::cout << "1 digit - expect 4, got " << checksum("6") << std::endl;
Now let's get this one working - this gives us conversion from character to digit and back, at least:
char checksum(const char *s)
{
int digit = *s - '0';
return '0' + 10 - digit;
}
Let's try 2 digits:
std::cout << "1 digit - expect 6, got " << checksum("11") << std::endl;
And now our test fails again. So add some more processing, to make this pass (and not break the single-digit test):
char checksum(const char *s)
{
int sum = 0;
int digit = *s - '0';
sum += digit;
++s;
if (*s) {
digit = *s - '0';
sum += 3 * digit;
}
return '0' + (10 - sum)%10;
}
We're probably ready to make this into a loop now. Once that's passed, we no longer need the short tests, and I have:
#include <iostream>
char checksum(const char *s)
{
int sum = 0;
for (int mul = 1; *s; ++s) {
int digit = *s - '0';
sum += mul * digit;
mul = 4 - mul;
}
return '0' + (1000 - sum)%10;
}
int test(const char *name, char expected, const char *input)
{
char actual = checksum(input);
if (actual == expected) {
std::cout << "PASS: " << name << ": "
<< input << " => " << actual
<< std::endl;
return 0;
} else {
std::cout << "FAIL: " << name << ": "
<< input << " => " << actual
<< " - expected " << expected
<< std::endl;
return 1;
}
}
int main()
{
int failures = 0;
failures += test("Book 1", '3', "978032114653");
failures += test("Book 2", '0', "978020163361");
return failures > 0;
}
I factored out the actual checking into a function here, so we can keep count of failures, and exit with the appropriate status, but everything else is as I described above.
You'll want to add a few more test cases - in particular, make sure the function correctly returns the extreme values 0 and 9 when it should.
There is one clear bug in your code: you are not allocating enough space in for ISBNinput. You should make it one character longer:
const int LENGTH = 13;
The reason for this is that that character-array strings are terminated with an extra null character. You might be lucky and the next byte in memory could sometimes happen to be a null byte, in which case the program would still work sometimes.
If you run the program with valgrind or a similar memory checker you are likely to see an error as the program access memory beyond what was allocated on the stack.
Also I think there is another bug. I think that mul should be initialized to 1.
By the way, this code is very fragile, depending on you entering no more than 12 characters, all of which are assumed to be digits. It might be OK as a quick hack for a proof-of-concept, but should not be used in any real program.