Why I cant print initials of a name? - cs50

I am trying to write a code that prints initials of a given name? I have been getting error whenever I use '/0' - to initialize the ith character of a given string. I am using it to identify initials of the 2nd word? Any suggestions to detect the 2nd word and print the initial of the 2nd word? Additionally, I am trying to write this code so that it ignores any additional spaces:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
printf ("Enter you Name:");//print name
string s = get_string(); //get input from user
printf("%c", toupper(s[0])); // use placeholder to call the string
for (int i=0, n = strlen(s); i < n; i++)
{
if (s[i] == '/0')
{
printf("%c", toupper(s[i+1]));
}
}
printf ("\n");
}

I'm not sure what your get_string() function does but this does what you're asking for.
int main(void)
{
printf ("Enter you Name:");//print name
char input[100];
cin.getline(input, sizeof(input));
string s(input);
//get input from user
printf("%c", toupper(s[0])); // use placeholder to call the string
for (int i=0, n = s.length(); i < n; i++)
{
if (isspace(s.at(i)))
{
printf("%c", toupper(s[i+1]));
}
}
printf ("\n");
}

Try to use ' ' instead of '/0'.
if (s[i] == ' ')
or if you prefer ASCII codes (Space is 0x20 or 32 as decimal):
if (s[i] == 0x20)
your code will work if there is only 1 space between names. To avoid this, the condition should also check the next char. If it's not a space then probably it's a 'letter':
if (s[i] == 0x20 && s[i+1] != 0x20) {...
Note that the for cycle should stop at i < n - 1, otherwise the loop will fail if there are trailing spaces...

Related

Why am I getting same characters with any key I type?

Why am I getting this return 4 repeated characters for Pset2 Substition CS50
Everything seems to work fine except for the checking for repeated characters in the command line argument. Rest of the code works fine when I remove this return for the checking repeated characters. Everything I type gives me this error
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
int main(int argc, string argv[])
{
if (argc == 2)
{
//When there are 26 characters in string
if (strlen(argv[1]) == 26)
{
string check = argv[1];
//Checking each characters in string(array) where [i] is the array number
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
//If the characters in the string is alphabet or not
if (!isalpha(argv[1][i]))
{
printf("Key must only contain Alphabetic Characters\n");
return 3;
}
//Check for repeated alphabet
for (int l = 0; l < n; l++)
{
if (argv[1][i] == check[l])
{
printf("Key must not contain repeated Characters\n");
return 4;
}
}
}
//Get Plaintext
string plaintext = get_string("Plaintext: ");
//Going through each characters in string
for (int j = 0, n = strlen(plaintext); j < n; j++)
{
//For LOWERCASE CHARACGERS
if (plaintext[j] >= 'a' && plaintext[j] <= 'z')
{
plaintext[j] = argv[1][plaintext[j] - 97];
plaintext[j] = tolower(plaintext[j]);
}
//For UPPERCASE CHARACTERS
else if (plaintext[j] >= 'A' && plaintext[j] <= 'Z')
{
plaintext[j] = argv[1][plaintext[j] - 65];
plaintext[j] = toupper(plaintext[j]);
}
}
printf("Ciphertext: %s\n",plaintext);
}
//If Characters are not 26 in string
else
{
printf("Key must contain 26 Characters\n");
return 2;
}
}
//When Location is other than argv[1]
else
{
printf("./substitution KEY\n");
return 1;
}
}
When i is 0 and l is 0 what is being compared here if (argv[1][i] == check[l])? Actually whenever i and l are equal it is comparing a character to itself. Program does not need to compare any characters it has already processed. The compare should start at the current char + 1.

pset2 readability always printing before grade 1 no matter what input

I know this is a fairly newbie question so I'm sorry if the solution is painfully obvious to you guys.
I've fully coded up pset 2 readability and it worked for printing out the number of letters, words and sentences for the user inputted text- I have since removed those print statement as they aren't needed for the pset (I just wanted to actually make sure the functions were returning something- they worked just fine).
I'm up to printing out the grade level now but no matter what text I input I only get before grade 1. I've already checked to see if I had anything wrong with my print statements and I can seem to find an issue there so I'm thinking that there may be an error in the calculation of the grade level itself- I've looked until my eyes have gone square and for the life of me I can not see anything wrong.
If someone could shed some light on my problem I would love to be saved the headache :), or even point me in the right direction so I get the learning. (also first time poster, long time lurkers so forgive me if anything is formatted incorrectly).
Thank you all!
Here is my code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
// my functions to calculate letters, words
int count_letters(string text);
int count_words(string text);
int count_sentences(string text);
int main(void)
{
string text = get_string("Text: ");
int letters = count_letters(text);
int words = count_words(text);
int sentences = count_sentences(text);
float calculation = (0.0588 * letters / words * 100) - (0.296 * sentences / words *
100) - 15.8;
int index = round(calculation);
if (index < 1)
{
printf("Before grade 1.\n");
}
else if (index >= 16)
{
printf("Grade: 16+.\n");
}
else
{
printf("Grade: %i.\n", index);
}
}
int count_letters(string text)
{
int letters = 0;
for (int i = 0; i < strlen(text); i++)
//((text[i] > 65 && text[i] < 90) || (text[i] > 97 && text[i] < 122))
if (isalpha(text[i]))
{
letters++;
}
return letters;
}
int count_words(string text)
{
int words = 0;
for (int i = 0; i < strlen(text); i++)
if isspace ((text[i]))
{
words++;
words = words + 1;
}
return words;
}
int count_sentences(string text)
{
int sentences = 0;
for (int i = 0; i < strlen(text); i++)
if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
sentences++;
}
return sentences;
}
I just wanted to actually make sure the functions were returning something- they worked just fine
Yes, the functions return "something" but is it the right thing? Suggest you add back the debug printf and look at the results carefully and critically. Start with the simplest text ("One fish. Two fish. Red fish. Blue fish."). 29 letters, 8 words, 4 sentences. What result is printed?
Inside of the function count_words
you have an if statement, if statements need to have brackets, the line wouldn't make sense even if you had the brackets, so double-check the logic as well.

Extra characters and symbols outputted when doing substitution in C

When I run the code using the following key, extra characters are outputted...
TERMINAL WINDOW:
$ ./substitution abcdefghjklmnopqrsTUVWXYZI
plaintext: heTUXWVI ii ssTt
ciphertext: heUVYXWJ jj ttUuh|
This is the instructions (cs50 substitution problem)
Design and implement a program, substitution, that encrypts messages using a substitution cipher.
Implement your program in a file called substitution.c in a ~/pset2/substitution directory.
Your program must accept a single command-line argument, the key to use for the substitution. The key itself should be case-insensitive, so whether any character in the key is uppercase or lowercase should not affect the behavior of your program.
If your program is executed without any command-line arguments or with more than one command-line argument, your program should print an error message of your choice (with printf) and return from main a value of 1 (which tends to signify an error) immediately.
If the key is invalid (as by not containing 26 characters, containing any character that is not an alphabetic character, or not containing each letter exactly once), your program should print an error message of your choice (with printf) and return from main a value of 1 immediately.
Your program must output plaintext: (without a newline) and then prompt the user for a string of plaintext (using get_string).
Your program must output ciphertext: (without a newline) followed by the plaintext’s corresponding ciphertext, with each alphabetical character in the plaintext substituted for the corresponding character in the ciphertext; non-alphabetical characters should be outputted unchanged.
Your program must preserve case: capitalized letters must remain capitalized letters; lowercase letters must remain lowercase letters.
After outputting ciphertext, you should print a newline. Your program should then exit by returning 0 from main.
My code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc,string argv[])
{
char alpha[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
string key = argv[1];
int totalchar = 0;
for (char c ='a'; c <= 'z'; c++)
{
for (int i = 0; i < strlen(key); i++)
{
if (tolower(key[i]) == c)
{
totalchar++;
}
}
}
//accept only singular 26 key
if (argc == 2 && totalchar == 26)
{
string plaint = get_string("plaintext: ");
int textlength =strlen(plaint);
char subchar[textlength];
for (int i= 0; i< textlength; i++)
{
for (int j =0; j<26; j++)
{
// substitute
if (tolower(plaint[i]) == alpha[j])
{
subchar[i] = tolower(key[j]);
// keep plaintext's case
if (plaint[i] >= 'A' && plaint[i] <= 'Z')
{
subchar[i] = (toupper(key[j]));
}
}
// if isn't char
if (!(isalpha(plaint[i])))
{
subchar[i] = plaint[i];
}
}
}
printf("ciphertext: %s\n", subchar);
return 0;
}
else
{
printf("invalid input\n");
return 1;
}
}
strcmp compares two strings. plaint[i] and alpha[j] are chars. The can be compared with "regular" comparison operators, like ==.

Vigenere.c CS50 Floating Point Exception (Core Dumped)

I am working on the Vigenere exercise from Harvard's CS50 (in case you noticed I'm using string and not str).
My program gives me a Floating Point Exception error when I use "a" in the keyword.
It actually gives me that error
when I use "a" by itself, and
when I use "a" within a bigger word it just gives me wrong output.
For any other kind of keyword, the program works perfectly fine.
I've run a million tests. Why is it doing this? I can't see where I'm dividing or % by 0. The length of the keyword is always at least 1. It is probably going to be some super simple mistake, but I've been at this for about 10 hours and I can barely remember my name.
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main (int argc, string argv[])
{
//Error message if argc is not 2 and argv[1] is not alphabetical
if (argc != 2)
{
printf("Insert './vigenere' followed by an all alphabetical key\n");
return 1;
}
else if (argv[1])
{
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if (isalpha((argv[1])[i]) == false)
{
printf("Insert './vigenere' followed by an all alphabetical key\n");
return 1;
}
}
//Store keyword in variable
string keyword = argv[1];
//Convert all capital chars in keyword to lowercase values, then converts them to alphabetical corresponding number
for (int i = 0, n = strlen(keyword); i < n; i++)
{
if (isupper(keyword[i])) {
keyword[i] += 32;
}
keyword[i] -= 97;
}
//Ask for users message
string message = GetString();
int counter = 0;
int keywordLength = strlen(keyword);
//Iterate through each of the message's chars
for (int i = 0, n = strlen(message); i < n; i++)
{
//Check if ith char is a letter
if (isalpha(message[i])) {
int index = counter % keywordLength;
if (isupper(message[i])) {
char letter = (((message[i] - 65) + (keyword[index])) % 26) + 65;
printf("%c", letter);
counter++;
} else if (islower(message[i])) {
char letter = (((message[i] - 97) + (keyword[index])) % 26) + 97;
printf("%c", letter);
counter++;
}
} else {
//Prints non alphabetic characters
printf("%c", message[i]);
}
}
printf("\n");
return 0;
}
}
This behavior is caused by the line keyword[i] -= 97;, there you make every 'a' in the key stream a zero. Later you use strlen() on the transformed key. So when the key starts with an 'a', keywordLength therefor is set to zero, and the modulo keywordLength operation get into a division by zero. You can fix this by calculating the keyword length before the key transformation.

Replacing and deleting a character from a string in c++?

This program is giving wrong output,, basically i want to remove the character specified and replace it by 'g'...For e.g: All that glitters is not gold if the user entered o then the output should be All that glitters is ngt ggld but the program is deleting all the characters from n onwards
#include <iostream>
using namespace std;
int main()
{
string input(" ALL GLItters are not gold");
char a;
cin>>a;
for(int i=0;i<input.size();i++)
{
if(input.at(i)==a)
{
input.erase(i,i+1);
input.insert(i,"g");
}
}
cout<<"\n";
cout<<input;
}
string& erase (size_t pos = 0, size_t len = npos);
The second parameter ( len ) is the Number of characters to erase.
You have to put 1 not i+1 :
input.erase(i,1);
http://www.cplusplus.com/reference/string/string/erase/
Why not replace it directly? Replace your for loop with this:
for (char& c : input)
{
if (c == a)
c = 'g';
}
Live example here.

Resources