user input in c - c

I cannot figure out how to take away a letter dependent on user input. For example, if I enter b the code should output cdefghijklmno... If I enter c the code should output defghijklmno... I just don't know where to do the math?
#include <stdio.h>
int main(void) {
char letter;
printf("Type one letter of alphabet and following letters will appear (lowercase): ");
scanf_s("%c", &letter);
if (letter >= 'a' && letter <= 'z'){
printf("%c, valid entry!\n\n", letter);
for (letter = 'a'; letter <= 'z'; ++letter){
printf("%c ", letter);
}
} else {
printf("%c, invalid entry.\n\n", letter);
}
return 0;
}

In this line:
for (letter = 'a'; letter <= 'z'; ++letter){
why do you start at a? Dont you want to start one after the user input letter, which is stored in letter?
So do that:
for (++letter; letter <= 'z'; ++letter){

if I enter b the code should output cdefghijklmno... If I enter c the code should output defghijklmno... I just don't know where to do the math
As #Ben has suggested, change your for loop to :
for (++letter; letter <= 'z'; ++letter)
{
printf("%c ", letter);
}
The reason of using ++letter is to print the alphabets which come after the entered letter up to z
This would do the job
further, from OP's comment:
To give the user repeated chances if input is incorrect
using a while loop would be helpful :
while( (scanf(" %c",&letter) == 1) && letter!='*')
{
if (letter >= 'a' && letter <= 'z')
{
printf("%c, valid entry!\n\n", letter);
for (++letter; letter <= 'z'; ++letter)
{
printf("%c ", letter);
}
printf("\n\n");
// break;
// place the above break if you want to stop scanning after first successful entry
}
else
{
printf("%c, invalid entry.\n", letter);
printf("try again\n\n");
}
}
this loop would continue till the use enters * (an asterik)
Note : while( (scanf(" %c",&letter) == 1) && letter!='*') here, we check whether scanf() successfully scanned or not and whether the scanned element is * or not
sample input :
1
2
a
t
3
*
output :
Type one letter of alphabet and following letters will appear (lowercase):
1, invalid entry.
try again
2, invalid entry.
try again
a, valid entry!
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
t, valid entry!
u v w x y z
3, invalid entry.
try again
*
ended

Try to increment the letter variable by 1 in for loop parameter:
for (letter += 1; letter <= 'z'; ++letter){
printf("%c ", letter);
}

You can also do it this way:
#include <stdio.h>
#include <ctype.h>
#define MAX 122
int
main(void) {
char letter;
int i;
printf("Type one letter of the alphabet(lowercase): ");
scanf("%c", &letter);
if (islower(letter)) {
printf("%c, valid entry!\n\n", letter);
for (i = letter + 1; i <= MAX; i++) {
printf("%c", i);
}
} else {
printf("%c, invalid entry.\n\n", letter);
}
return 0;
}

Related

How to count the number of words with more than 3 same letters

My program counts the number of words with 3 letters but I need to count the words with 3 identical letters. I am trying to write a program that counts the number of words that have more than three letters. The program has to end when a period is entered. My code works, but it scores all words with 3 letters
#include <stdio.h>
#include <stdlib.h>
int main() {
char c;
int cont = 0, counterLargerThanThree = 0;
printf("Enter a phrase that ends with a period:\n");
do {
c = getchar();
if (c != ' ' && c != '.') {
++cont;
} else {
if (cont == 3) {
counterLargerThanThree++;
}
cont = 0;
}
} while (c != '.');
printf("%i \n", counterLargerThanThree);
system("pause");
return 0;
}
All you've to do is modify the logic of incrementing your result.
When you're taking a character other than space and ., that means, when the condition if (c != ' ' && c != '.') is true, increment frequency of the character
In other case, that means when the above condition is false, check if the last word you've taken as input has 3 same characters. If it has then increment your result.
Sample code:
int main()
{
char c;
int wordWithThreeSameLetter = 0;
int frequency[26]; // assuming there'll be only small letters in input
for(int i = 0; i < 26; i++)
{
frequency[i] = 0; // initializing the count of every character
}
printf("Enter a phrase that ends with a period:\n");
do
{
c = getchar();
if (c != ' ' && c != '.')
{
frequency[c - 'a']++; // incrementing count of the character
}
else
{
for(int i = 0; i < 26; i++)
{
if(frequency[i] == 3) wordWithThreeSameLetter++; // counting word with 3 same letter
frequency[i] = 0; // initializing the count for future word
}
}
}
while (c != '.');
printf("%i \n", wordWithThreeSameLetter);
system("pause");
return 0;
}
Input:
a
b
c
e
f
e
g
e
x
y
y
o
y
.
Output: 2
Input:
a
b
c
d
e
e
f
.
Output: 0
N.B. -
As you haven't mentioned specifically about input format, I assumed there'll be only small letter character , space and . in input. So above code will work only for such input.

How to write a program that reads a message and counts the number of alph and digits then, replaces lower case by upper case characters?

i want to use the same inputed message for the second part of the code but i can't. the first part is to count the number of alphabets and digits and the second part is to replace lower case by upper case characters. help me please!!
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MESSAGE 100
int main()
{
char message[MESSAGE];
int alphabet, digit, i;
alphabet = digit = i = 0;
printf("Please enter your message:\n");
fgets(message, sizeof message, stdin);
while (message[i] != '\0')
{
if ((message[i] >= 'a' && message[i] <= 'z')
|| (message[i] >= 'A' && message[i] <= 'Z'))
{
alphabet++;
}
else if (message[i] >= '0' && message[i] <= '9')
{
digit++;
}
else
{
i++;
}
printf("Number of Alphabets in the string is : %d\n", alphabet);
printf("Number of Digits in the string is : %d\n", digit);
scanf("%i", message);
int count, ch, i;
for (i = 0; (message[i] = getchar()) != '\n'; i++)
{
;
}
message[i] = '\0';
count = i;
printf("The given message is:%s\n", message);
printf("Case changed message is:\n");
for (i = 0; i < count; i++)
{
ch = islower(message[i]) ? toupper(message[i]) : tolower(message[i]);
putchar(ch);
}
return 0;
}
}
The following proposed code:
cleanly compiles
performs the desired operation(s)
produces the expected output
follows the axiom: only one statement per line and (at most) one variable declaration per statement.
minimizes the scope of the variable i
since the numbers can never be less than 0, uses size_t rather than int in the variable definitions
properly checks for I/O errors and when an error occurs, passes the error message and the text reason the system thinks the error occurred to stderr
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MESSAGE 100
int main( void )
{
char message[MESSAGE];
size_t alphabet = 0;
size_t digit = 0;
printf("Please enter your message:\n");
if( ! fgets(message, sizeof message, stdin) )
{
perror( "fgets failed:" );
exit( EXIT_FAILURE );
}
printf( "The given message is:%s\n", message );
for( size_t i = 0; message[i]; i++ )
{
if ( isalpha( message[i] ) )
{
alphabet++;
message[i] = (islower(message[i]) ) ? (char)toupper(message[i]) : (char)tolower(message[i]);
}
else if ( isdigit( message[i] ))
{
digit++;
}
}
printf("Number of Alphabets in the string is : %zu\n", alphabet);
printf("Number of Digits in the string is : %zu\n", digit);
printf("Case changed message is: %s\n", message );
}
Just coded again:
#include <stdio.h>
#include <ctype.h>
#define MESSAGE 100
int main(void) {
char msg[MESSAGE];
int alphabet = 0;
int digit = 0;
printf("Enter a message: ");
fgets(msg, sizeof msg, stdin); // accepting the text
for (int i = 0; msg[i]; i++) { // msg[i] says -> msg[i] != '\0'
if (isalpha(msg[i])) alphabet++; // counting if alphabet occurs
if (isdigit(msg[i])) digit++; // counting if a digit occurs
}
for (int i = 0; msg[i]; i++)
msg[i] = (isupper(msg[i])) ? tolower(msg[i]) : toupper(msg[i]);
// converting from upper to lower and vice versa
// printing the details of the given text
printf("There are %d letters and %d digits in the message.\n", alphabet, digit);
// printing the converted text
printf("The converted text is: %s\n", msg);
return 0;
}
In the aforementioned code, the program will ask to get an input from the user and count both alphabet and digit wherever they're occurred and notice that here we've used isdigit() just to count if the letter given was a digit until the null-terminator occurs in the first For loop.
In the second loop, we've just converted each of the letter from upper to lower and vice versa and assigned them again into the same variable and printed them when the loop is exited successfully.
Also, notice that the punctuation marks ain't the member of either alphabet letters or digit, so they're not counted anywhere.
As a sample output:
Enter a message: Hello world, how are you 1234 doing?
There are 24 letters and 4 digits in the message.
The converted text is: hELLO WORLD, HOW ARE YOU 1234 DOING?
Do you have a clear question?
For the second part an easy trick is to look at an ASCII table and notice that 'A' is decimal 65 and 'a' is decimal 97. There is a difference of 32 between these so you can do a bitwise operation on all letters to convert to uppercase without converting the uppercase letters to lower.
This will mess up your numbers though, so you need to make sure you don't run this on those.
If you want to convert the same message then you don't need to input that again inside the while loop. Also, you have to increment 'i' for every case, if the current character is alphabet or digit, so don't put it in the else part.
Try the following implementation:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MESSAGE 100
int main()
{
char message[MESSAGE];
int alphabet, digit, i;
alphabet = digit = i = 0;
printf("Please enter your message:\n");
fgets(message, sizeof message, stdin);
while (message[i] != '\0')
{
if ((message[i] >= 'a' && message[i] <= 'z')
|| (message[i] >= 'A' && message[i] <= 'Z'))
{
alphabet++;
}
else if (message[i] >= '0' && message[i] <= '9')
{
digit++;
}
i++;
}
printf("Number of Alphabets in the string is : %d\n", alphabet);
printf("Number of Digits in the string is : %d\n", digit);
scanf("%s", message);
int count, ch;
message[i] = '\0';
count = i;
printf("The given message is:%s\n", message);
printf("Case changed message is:\n");
for (i = 0; i < count; i++)
{
ch = islower(message[i]) ? toupper(message[i]) : tolower(message[i]);
putchar(ch);
}
return 0;
}
"Don't tell me there's not one bit of difference between uppercase and lowercase letters, because that's exactly the difference."
In ASCII, you can toggle case by toggling the 6th least-significant bit.
'A' == 0x41 <-> 0x61 == 'a'
'B' == 0x42 <-> 0x62 == 'b'
'C' == 0x43 <-> 0x63 == 'c'
...
'Z' == 0x5A <-> 0x7A == 'z'
That provides an easy of changing the case, and we can do it all in one pass.
if (
( message[i] >= 'A' && message[i] <= 'Z' )
|| ( message[i] >= 'a' && message[i] <= 'z' )
) {
++letters;
message[i] ^= 0x20;
}
else if ( message[i] >= '0' && message[i] <= '9' ) {
++digits;
}
This, like your original program, makes the following assumptions:
The program will be compiled on an ASCII-based machine.
The program will be compiled for an ASCII-based machine.
You are only interested in the letters and digits in the ASCII character set.

Alphabet and code ascii

I am trying to create a program in c language that gets a number and a string, for example the number is 3 and the string is "Zig".
The output should be alphabet's codes + the number. If the character's number goes more than "Z" (90) it should start from "A" again. Similarily, for lower case characters, when going beyond "z" start again from "a".
input : "Zig"
number : 3
output : "Clj"
I have a problem with the part that it should start from A(for capitals) & a again.
this is my code now ! I have a problem with rotation part how to start from A or a again :)
char a[50];
int n,i;
printf("enter your number:\t");
scanf("%d",&n);
printf("enter your string:\t");
fflush(stdin);
gets(a);
while('A'<= a[i] <= 'Z'){
if(a[i]+n > 'Z'){
}
else{
a[i]=a[i]+n;
}
i++;
}
while('a' <= a[i] <= 'z'){
if(a[i]+n > 'z'){
}
else{
a[i]=a[i]+n;
}
i++;
}
printf("string:\n");
puts(a);
}
Fixed Bug
#include <stdio.h>
#include <strings.h>
int main(){
char str [80];
int number;
printf ("Enter your string: ");
scanf ("%79s",str);
printf ("Enter your number: ");
scanf ("%d",&number);
for(int i= 0; i < strlen(str);i++){
str[i]+=number;
while(str[i]>'Z' && str[i] < 'a'){
str[i] = 'A'+ str[i] - 'Z';
}
while(str[i]>'z'){
str[i] = 'a'+ str[i] - 'z';
}
}
printf("%s",str);
}
I have a problem with the part that it should start from A(for capitals) & a again
When you get to Z (decimal 90) you can easily subtract 25 (ASCII char "EM") to get back to A (decimal 65). Similarly you can repeat subtraction of 25 when you reach z and it will cycle back to

Vigenere's cipher in C several problems

I have made program which encrypts and decrypts Vigenere's cipher but I have several problems.
Here is one: First letter of sentence is encrypted incorrectly.
Second one: After sentence I have letter K. I think that's because of space but I don't know how to fix it.
And third problem: There are no spaces in encrypted sentence I know ages ago when Vigenere's cipher was used there were no spaces but I would like to have groups of 5 letters if that's possible.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char **argv) {
char message[100];
int choice;
int i, j;
char pass[33];
int value;
char repeat = 1;
while (repeat == 1) {
printf("Enter operation\n");
printf("Encrypt - 1 \n");
printf("Decrypt - 2\n");
scanf("%d", &choice);
if (choice == 1) {
printf("Please enter message to encrypt\n");
while (getchar() != '\n');
fgets(message, 100, stdin);
printf("Enter password\n");
scanf("%s", &pass);
for (i = 0, j = 0; i < strlen(message); i++, j++) {
if (message[i] == ' ')
continue;
if (j >= strlen(pass)) {
j = 0;
}
if (!isupper(message[i])) {
value = (((message[i]) - 97) + ((pass[j]) - 97));
}
if (!islower(message[i])) {
value = (((message[i]) - 65) + ((pass[j]) - 65));
}
printf("%c", 97 + (value % 26));
}
printf("\nWould you like to repeat? [1/0]\n");
scanf("%d", &repeat);
} else
if (choice == 2) {
printf("Enter message do decrypt\n");
while (getchar() != '\n');
fgets(message, 100, stdin);
printf("Zadejte heslo\n");
scanf("%s", &pass);
for (i = 0, j = 0; i < strlen(message); i++, j++) {
if (message[i] == ' ')
continue;
if (j >= strlen(pass)) {
j = 0;
}
if (!isupper(message[i])) {
value = (((message[i]) - 96) - ((pass[j]) - 96));
}
if (!islower(message[i])) {
value = (((message[i]) - 64) - ((pass[j]) - 64));
}
if (value < 0) {
value = value * -1;
}
printf("%c", 97 + (value % 26));
}
printf("\nWould you like to repeat? [1/0]\n");
scanf("%d", &repeat);
}
}
return (EXIT_SUCCESS);
}
[
The main problem in your code is you apply the translation to characters with incorrect tests: you should translate uppercase letters is you have indeed an uppercase letter, not if you don't have a lowercase character. As coded, non letters are translated twice.
Change the code to:
if (islower((unsigned char)message[i])) {
value = (((message[i]) - 'a') + ((pass[j]) - 'a'));
}
if (isupper((unsigned char)message[i])) {
value = (((message[i]) - 'A') + ((pass[j]) - 'a'));
}
Also make sure you use character constants instead of hard-coded ASCII values and make the password lowercase.
In the deciphering case, the offsets seem incorrect. You should be using 'A' and 'a' too.
First things first, the message corruption. If you add a few printf() statements in the loop that is doing the encryption, you should be able to get an idea what is going wrong. You can always comment them out, or remove them altogether, anytime later.
That K on the end could be the encrypted \n that would have been read in with the message.
To display the encrypted message in groups of five characters, keep a count of how many characters you have actually displayed (make sure the instruction to increase the count is located where it will get skipped if the character is not displayed); and when this reaches 5, display a space and reset the counter to zero.

Using c code to make a caesar cipher?

Hello good people of the stack overflow.
Explanation
I am trying to to the following.
My program needs to take a stream of letters as the input and then for the output rotate 13 paces forward.
For example
A becomes N
B becomes O
C becomes P
D becomes Q
and so on
For this program I need to use the ascii table. So for example lower case a=97 once my program is done it becomes n=110
I wrote a little formula for this
c=(c+13-97)% 26+97 where c is my letter. as you can see if c=97 then c will end up being 110.
So here is my program
As it is seen I used an if statment to determine if I have a capital or lower case letter.
/* 97 is lower case a in ascii and 122 is lower case z*/
# include <stdio.h>
int main() {
char c;
printf("please enter a character:");
while (c!=-1) {
c=getchar();
putchar (c);
if ( c>=97 && c<=122) {
c=(c+13-97)% 26+97 ;
printf("%c \n " ,c);
}
else
c=(c+13-65) % 26 +65 ;
printf("%c \n " ,c);
}
return 0;
}
My problem is with the output for example if I plug in a
instead of n I get
an
n
1
Your code is absolutely fine with some minor changes in it.
/* 97 is lower case a in ascii and 122 is lower case z*/
# include <stdio.h>
int main()
{
char c;
printf("please enter a character:");
while (c!=-1)
{
c=getchar();
//putchar (c); // Avoid Printing entered character
if ( c>=97 && c<=122)
{
c=((c+13-97)% 26)+97 ;
printf("%c \n " ,c);
}
else
{ // Braces missing
c=((c+13-65) % 26) +65 ;
printf("%c \n " ,c);
}
return 0;
}
}
Output :
please enter a character : a
n
One other issue that you will run into is the need to flush the \n remaining in the input buffer before reading the next character. Basically, what occurs is after a character is entered and the user presses Enter, c is read from the input buffer, but '\n' remains. So the next time the loop is entered \n is already present in the input buffer and is taken as c for that iteration.
To prevent this from occurring, the easiest way to flush the input buffer is to declare a throw-away int say int flush and following each read of a character, add the following:
do { flush=getchar(); } while (flush != '\n');
This will extract all remaining characters from the input buffer preparing it for the next read. (Note: fflush does not do this for input streams) An implementation with this incorporated is:
#include <stdio.h>
int main () {
int c = 0; /* Always initialize variables */
int flush = 0;
int new = 0;
printf ("\nPlease enter a character (ctrl+d to exit):\n\n");
while (printf (" char: ") && (c = getchar()) != -1) {
do { flush=getchar(); } while (flush != '\n'); /* flush input buffer */
if (c >= 'a' && c <= 'z')
{
new = (c + 13 - 97) % 26 + 97;
printf ("\t lower-case '%c' becomes: '%c'\n\n", c, new);
}
else if (c >= 'A' && c <= 'Z')
{
new = (c + 13 - 65) % 26 + 65;
printf ("\t upper-case '%c' becomes: '%c'\n\n", c, new);
}
else
{
printf ("\n invalid character, try again\n\n");
}
}
printf ("\n\nexiting.\n\n");
return 0;
}
output:
Please enter a character (ctrl+d to exit):
char: a
lower-case 'a' becomes: 'n'
char: b
lower-case 'b' becomes: 'o'
char: n
lower-case 'n' becomes: 'a'
char: o
lower-case 'o' becomes: 'b'
char: A
upper-case 'A' becomes: 'N'
char: B
upper-case 'B' becomes: 'O'
char: N
upper-case 'N' becomes: 'A'
char: O
upper-case 'O' becomes: 'B'
char:
exiting.
Good luck with your project. Drop a comment if you run into additional problems.
Multiple Character Version Using getline
Regarding your question about line input. Here is a version using getline to read multiple characters from stdin:
#include <stdio.h>
int main () {
int new = 0;
ssize_t nread = 0; /* number of chars read by getline */
char *line = NULL; /* string holding chars - getline allocates when NULL */
size_t n = 0; /* limit number of bytes to (ignored when 0) */
char *p = NULL; /* point to use to iterate over each char in line */
int index = 0; /* simple index for formatted output. */
printf ("\nPlease enter characters to translate (ctrl+d to exit):\n");
while (printf ("\n input: ") && (nread = getline (&line, &n, stdin) != -1)) {
index = 0; /* reset index */
p = line; /* assign pointer to line */
printf ("\n"); /* just because it looks nice */
while (*p != '\n') /* getline consumes the '\n' */
{
if (*p >= 'a' && *p <= 'z')
{
new = (*p + 13 - 97) % 26 + 97;
printf ("\t char[%2d] : %c => %c\n", index, *p, new);
}
else if (*p >= 'A' && *p <= 'Z')
{
new = (*p + 13 - 65) % 26 + 65;
printf ("\t char[%2d] : %c => %c\n", index, *p, new);
}
else
{
printf ("\n char[%2d] : %c => invalid character\n", index, *p);
}
p++;
index++;
}
}
printf ("\n\nexiting.\n\n");
return 0;
}
output:
Please enter characters to translate (ctrl+d to exit):
input: aAbBcCmMnNoO
char[ 0] : a => n
char[ 1] : A => N
char[ 2] : b => o
char[ 3] : B => O
char[ 4] : c => p
char[ 5] : C => P
char[ 6] : m => z
char[ 7] : M => Z
char[ 8] : n => a
char[ 9] : N => A
char[10] : o => b
char[11] : O => B
input:
exiting.
The while loop should be
while ((c=getchar()) != EOF)
Your code is checking the value of c before c is initialized. You should have gotten a warning about that.
You should not be using hard-coded ASCII values in your code. Lower case a is 'a'. Lower case z is 'z'. So, for example, you can write
if ( c >= 'a' && c <= 'z' )
Note that stdin buffers characters until you press the return key. When you do press the return key, getchar will give you the character that you typed followed by a newline '\n' character. Your code only handles lower case and upper case characters. You need to modify the code to handle non-alpha characters correctly, e.g. spaces, punctuation, newlines.

Resources