The output is wonky when I use numbers 4-22, and I can't figure out why. Help would be greatly appreciated, and I would also like to know why this does not work.
#include<cs50.h>
#include<stdio.h>
#include<string.h>
int main(void)
{
int shifts;
int enc;
printf("What is your message ");
string message = get_string();
printf("By how many letters do you want to shift?");
scanf("%d",&shifts);
for(int i=0;i<strlen(message);i++)
{
enc=((message[i] - 89)+shifts)%26;
printf("%c",enc + 89);
}
printf("\n");
}
Inside the for loop you should check whether the character is uppercase, lowercase or neither. The number 89 is also wrong, that is 'Y', what you probably want is 65 or 97, 'a' and 'A' respectively. The for loop should be changed to be something like:
#include <ctype.h> // For isupper()/islower()
for(int i = 0; i < strlen(message); i++)
{
if(isupper(message[i])) { // Check if current char is uppercase
enc=((message[i] - 'A')+shifts)%26; // Apply cipher
printf("%c",enc + 'A');
} else if(islower(message[i])) { // Check if current char is lowercase
enc=((message[i] - 'a')+shifts)%26; // Apply cipher
printf("%c",enc + 'a');
} else { // Print char without change
printf("%c", message[i]);
}
}
Note the use of 'A' and 'a' instead of 65 and 97, these will translate to the corresponding integer literals at compile time. There are other ways to write this, this probably isn't even the most clean way to do it (multiple printf()s for example), but it should illustrate how this works and should be done.
Related
I have been writing a program to input a phrase and turn it into an acronym. For some reason when I output my acronym at the moment it comes out with a bunch of random characters. How do I fix it?
#include <stdio.h>
#include <string.h>
#define MAXLEN 50
int main() {
int num;
printf("Enter number of acronyms to add to the database:");
scanf("%d", &num);
getchar();
char strings[num][MAXLEN];
char acronym[num][MAXLEN];
for(int i = 0; i < num; i++){
printf("Enter the string to convert into an acronym:");
fgets(strings[i],MAXLEN,stdin);
printf("%s\n", strings[i]);
for(int j = 0; j < 11; j++){
if((strings[i][j]) >= 'A' && (strings[i][j]) <= 'Z'){
char buffer[][20] = {strings[i][j]};
strcat(acronym[i], buffer[i]);
}
}
puts(acronym[i]);
}
return 0;
}
I have tried changing the MAXLEN value to see if it was a memory issue or like a buffer overload. I've also just tried changing around how the strings switch and work together but nothing has worked.
char buffer[][20] = {strings[i][j]};
Here you let the compiler count how many elements the array has from the initialization.
It has 1 element, A string with single a single character strings[i][j] and rest of the 20 byte array filled with 0.
strcat(acronym[i], buffer[i]);
Here you access buffer[i], but there is only one string there (as explained above), so this is invalid if i is anything but 0.
I'm not sure what you are trying to do, but this would be valid implementation of what this code tries to do:
// extract single character as a string
char buffer[2] = {strings[i][j], 0}; // only one of 2 and 0 is mandatory
// append it to acronym
strncat(acronym[i], 20, buffer);
Probably lots of other stuff there is wrong, but here is one definite issue and a possible solution.
this is what i tried.
this works properly for small string like wel$co*me
but gives weird output for pass#word. where am i going wrong exactly?
#include <stdio.h>
#include <string.h>
int main()
{
char s[100],rs[100];
int i,c=0;
scanf("%s",s);
int n = strlen(s);
for(i=0;i<n;i++)
{
if(((int)s[i] >= 65 && (int)s[i] <= 90) ||((int)s[i] >=97 && (int)s[i] <= 122) )
{
rs[c] = s[i];
c++;
}
else
{
continue;
}
}
printf("%s",rs);
return 0;
}
but gives weird output for pass#word. where am i going wrong exactly?
printf("%s",rs); expects rs to be a pointer to a string. Yet without a certain null character in the data pointed to by rs, the result is undefined behavior or in OP's case, "weird output".
A simple solution is
rs[c] = '\0'; // add this after the loop
printf("%s",rs);
Another important one is to avoid buffer overruns - use a width limit.
// scanf("%s",s);
scanf("%99s",s);
Code has other weaknesses, yet this are the key ones for now.
#include "stdafx.h"
#include "stdlib.h"
#include <ctype.h>
int num = 0;
int i = 0;
int ch = 0;
int letter_index_in_alphabet(int ch) {
if (isalpha(ch) == true) {
char temp_str[2] = { ch };
num = strtol(temp_str, NULL, 36) - 9;
printf("%d is a letter, with %d as its location in the alphabet!", ch, num);
}
else {
return -1;
}
}
int main()
{
char input_str[10];
printf("Please enter a series of up to 10 letters and numbers: \n");
fgets(input_str, 10, stdin);
for (i == 0; i <= 10; i++) {
ch = input_str[i];
letter_index_in_alphabet(ch);
}
return 0;
}
Hello everyone, this is my first post on SOF! The goal of this program is to read characters from the standard input to EOF. For each character, report if it is a letter. If it is a letter, print out its respective index in the alphabet ('a' or 'A' = 1, 'b' or 'B' = 2..etc). I have been searching some other posts on stackoverflow and this has helped me get this far(using fgets and strtol functions). I have no visible syntax errors when I run this code, but after I enter a string of characters (ex: 567gh3fr) the program crashes.
Basically, I am trying to use 'fgets' to bring each character entered into a string with the appropriate index. Once I have that string, I check each index for a letter and if it is, I print the number assigned to that letter of the alphabet.
Any help or insight into why this isn't working as intended is greatly appreciated, Thanks!
You have a few problems.
First, char input_str[10] is only big enough for the user to enter 9 characters, not 10, because you need to allow one character for the null byte that ends a string.
Second, your loop goes too far. For a string with 10 characters, indexes go up to 9, not 10. It also should stop when it gets to the null byte, since the user might not have entered all 9 characters.
To get the position in the alphabet, you can simply subtract the value of A or a from the value of the character. Use tolower() or toupper() to convert the character to the case that you're going to use. Your method works, but it's overly complicated and confusing.
letter_index_in_alphabet() is declared to return int. But when the character is a letter, it doesn't execute a return statement. I'm not sure why it's supposed to return something, since you never use the return value, but I've changed it to return the position (maybe the caller should be the one that prints the message, so the function just does the calculation).
In the for loop, it should be i = 0 to perform an assignment, not i == 0 which is comparison.
You also shouldn't use global variables so much. And system header files should have <> around them, not "".
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int letter_index_in_alphabet(int ch) {
if (isalpha(ch)) {
int num = tolower(ch) - 'a' + 1;
printf("%d is a letter, with %d as its location in the alphabet!\n", ch, num);
return num;
} else {
return -1;
}
}
int main()
{
char input_str[10];
printf("Please enter a series of up to 9 letters and numbers: \n");
fgets(input_str, sizeof(input_str), stdin);
for (int i = 0; input_str[i]; i++) {
letter_index_in_alphabet(input_str[i]);
}
return 0;
}
Basically I have to create a caesar cipher, which is solely replacing each letter given with a letter that is int 'k' away. This takes 2 command line arguments: './caesar' and 'k', which given by the user. it works fine; but has one issue:
it encrypts "BARFOO" as "EDUIRR" using 3 as key which is correct
encrypts "BaRFoo" as "FeVJss" using 4 as key which is correct
BUT it does not encrypt "barfoo" as "onesbb" using 65 as key, it encrypts it as "oonneess|bb|bb" .
Please notice the punctuation; the caps and so on.
See the problem here? it also does this for other random words; it repeats letters. Help me....
PS: I am extremely new to programming, as you can see in my code, so please try to explain in english!
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
string s;
//int d;
int c;
int a;
if(argc != 2)
{
printf("Please run with a command line argument.");
return 1;
}
else
{
s = GetString();
}
int k = atoi(argv[1]);
for(int i = 0; i < strlen(s); i++)
{
a = s[i];
if(a<'A'||a>'z')
{
printf(" ");
}
else
{
if(a>='A'&&a<='Z')
{
c = a+k;
while(c>'Z')
{
c = 'A'+(c-'Z')-1;
printf("%c", c);
}
if(c<='Z')
{
printf("%c", c);
}
}
else if(a>-'a'&&a<='z')
{
c = a+k;
while(c>'z')
{
c = 'a'+(c-'z')-1;
printf("%c", c);
}
if(c<='z')
{
printf("%c", c);
}
}
}
}
printf("\n");
}
You can try to take k%26 since it should wrap around the characters of alphabet.
That should solve your problem.
You should try this way. Take the case of uppercase letters. First get the index from the letter 'A'.
index = a - 'A';
Then add the value in the variable k and get the remainder when divided with 26.
modified_index = ( index + k ) % 26;
Now to get the desired letter just add it with 'A'.
c = 'A' + modified_index;
Only adding k%26 will not help as that way 'z' with increment 1 will be turned into { which is wrong.
Also, if you just add value in k with the letter denoted by variable a it might cross the limit of ASCII characters as Joulin mentioned.
i am making a program that discard a letter from a list if you enter a letter, can anyone help me. thanks.
in example:
(BEFORE)
ABCDEFGHIJKLMNOPQRSTUVWXYZ
enter a letter: A
(AFTER ENTERING A LETTER 'A')
_BCDEFGHIJKLMNOPQRSTUVWXYZ
enter a letter:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
int main()
{
int alphabet[26];
char letter;
int i;
int j;
alphabet[0] = 'A';
for(i = 0;i < 26; i++)
{
alphabet[i] = alphabet[0];
printf ("%c", alphabet[i], alphabet[i]);
alphabet[0]++;
}
printf("\n\nenter the letter you want to remove in the alphabet: ");
scanf("%c", letter);
while(j<alphabet[i])
{
if(letter==alphabet[i])
{
j--;
}
}
}
The problem is its not removing the letter in the alphabet when i entered the letter i want to remove. please help. thanks.
EDIT: one last thing, how can i make it only one input?, i mean if i input the same letter in 2nd time it will said "you already input that letter".
You are assuming that the letters are contiguos, as in ASCII, but you cannot assume that in C.
The next line has a duplicated argument:
printf ("%c", alphabet[i], alphabet[i]);
Drop the last alphabet[i].
Your last if() sentence is wrong: the comparisson must be done with ==.
It is not clear at all what do you want to do.
EDIT:
I would do the program in this way:
#include <stdio.h>
int main()
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char letter;
printf("Choose a letter: ");
letter = getchar();
printf("\n\n");
for(int i = 0; i < 26; i++)
if (letter == alphabet[i])
{
alphabet[i] = '_';
break; /* This terminates the for() loop */
}
printf("Result: %s \n", alphabet);
}
EDIT2: I have changed the declaration of alphabet, because the string constant has to be modified later...
you are assigning a value to letter with the the statement
letter=alphabet[i]
this statement will always be true, unless alphabet[i] is 0.
use comparision instead
letter==alphabet[i]
also your while loop is a bit weird, as the value of j will be undefined in the beginning , so your comparision will be undefined.
while(j<alphabet[i])
{
if(letter=alphabet[i])
{
j--;
}
probably you simply want to do something like:
for(i = 0;i < 26; i++) {
if(alphabeth[i]==letter) {
alphabeth[i]='_';
}
}
if you only want to replace the first occurence of the letter, insert a break; after alphabeth[i]='_';
and you probably don't want to have magic values like "26" occuring multiple times in your sourcecode.
instead use something like
#define ALPHABETSIZE 26
and replace all occurences of 26 by ALPHABETSIZE
There are a few things here that you are doing to make it hard for yourself.
You need to use "==" not "=" to compare two variables
Your value for "j" is not initialised so "j--" would be undefined
Its probably better to keep all your types the same and make the array a "char" array not an "int" array.
To remove an element from your array "int alphabet[26];" would be very difficult, it would probably be easier to make this a "string" exercise. All you can really do is to make a "blank" letter by
alphabet[j] = ' ';
I think its possible to make a better design though if you explain your requirements more clearly :)
If I got you right you want to go through your array and check if the entered char matches any in the array.
Is there any reason, why you dont use a for-loop like this and set the array position to 0 instead of the while statement?
for(i=0;i<26;i++)
{
if(letter == alphabet[i])
alphabet[i] = "_"; // or setting it to 0 if you use and int-array
}
Or do I get something wrong here?