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
Related
I am trying to write a program that prompts people to re-enter their name if they put numbers or special characters in them. (Working on numbers first then I will do special characters).
My for loop is not acting as I expected it to. I wanted my for loop to go over every char in name[256], and check if it is a ... z || A ... Z. However, I am running into problems. See output below the code.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int age;
int i = 0; //for the loop
float height, weight;
char name[256];
char reason[256];
printf("--------------------------------\n");
printf("WRITE YOUR INFORMATION\n");
printf("--------------------------------\n");
printf("NAME : ");
fgets(name, 256, stdin);
while (name[i] != '\0')
{
if (name[i] != (name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z'))
{
printf("Enter your name again, no numbers.\n");
i++;
printf("NAME : ");
fgets(name, 256, stdin);
}
break;
}
printf("AGE :");
return 0;
}
This is when my input for fgets function is br4ndon, sure it worked good, but when i typed in br4ndon again, it passed by... it wasn't supposed to.
--------------------------------
WRITE YOUR INFORMATION
--------------------------------
NAME : br4ndon
Enter your name again, no numbers.
NAME : br4ndon
AGE :
Now this is an input with brandon
--------------------------------
WRITE YOUR INFORMATION
--------------------------------
NAME : brandon
Enter your name again, no numbers.
NAME : brandon
AGE :
How can I make sure that it only prompts to re-enter name if the charachter contains anything but a ... z || A ... Z?
There are many issues in your code:
you mix up the loop for the input of name and the loop that checks if none of the chars of name is anything else than a letter.
you omit the removal of the trailing \n after fgets(read the fgets documentation)
the condition name[i] != (name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') makes no sense at all.
You want something like this:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int age;
float height, weight;
char name[256];
char reason[256];
printf("--------------------------------\n");
printf("WRITE YOUR INFORMATION\n");
printf("--------------------------------\n");
while (1)
{
printf("NAME : ");
int nameok = 1;
fgets(name, 256, stdin);
name[strcspn(name, "\n")] = 0; // remove the `\n` at the end of name
for (int i = 0; i < strlen(name); i++)
{
if (!(name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z'))
{
// character not included in A..Z or a..z
nameok = 0;
break;
}
}
if (nameok)
break; // name is OK, we end the while loop
// name not OK: ask again
printf("Enter your name again, no numbers.\n");
continue;
}
printf("AGE :");
return 0;
}
There is still room for improvement:
Examples:
you should use isalpha from ctype.h (which you include already) instead of the awkward !(name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') condition.
you should make a function that asks for the name
fgets(name, 256, stdin) should rather be fgets(name, sizeof(name), stdin), so if you change the size of the name array, you only need to change it in one place
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.
I am completing a programming exercise and when my program is run, it never executes anything past the input line and never terminates. No errors or warnings are coming up so I'm not sure what is wrong. Any help would be great.
This is the assignment:
Write a function that asks the user to input a telephone number as a string containing a threedigit area code, followed by a seven-digit number. Any other characters will be ignored, and only
the first 10 digits will be considered. Assume that the string has at most 200characters.
If the user does not provide at least 10 digits, an error message should be printed out.
It should report the telephone number in the format (123) 456-7890. Note that the user may
choose any input format, yet the program should maintain a consistent output format.
The function should be called phone_fmt. Your executable will be called phone. The function
and main should be in the files phone_fmt.c, phone_fmt.h and phone.c, respectively.
This is my code for phone.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "phone_fmt.h"
int main(){
char numStr[200];
char phoneNum[14];
int i=0;
printf("Enter phone number string up to 200 characters: \n ");
scanf("%s", numStr);
if(strlen(numStr)<10){
printf("Invalid. Entry must be at least 10 characters.\n");
exit(1);
}
while(numStr[i] != '\0' && i<10){
if(numStr[i]>'0' && numStr[i]<'9')
break;
i++;
}
if(i > 10){
printf("Invalid. Not enough digits to complete phone number.\n");
exit(1);
}
phone_fmt(numStr, phoneNum);
printf("Phone number: %s \n", phoneNum);
return 0;
}
code for phone_fmt.c
#include "phone_fmt.h"
void phone_fmt(char *numStr, char *phoneNum){
int i=0;
int j=0;
int c=0;
while(numStr[i] != '\0' && c < 10){
if(j==0){
phoneNum[j]='(';
j++;
}
else if(j==4){
phoneNum[j]=')';
j++;
}
else if(j==8){
phoneNum[j]='-';
j++;
}
if(numStr[i] >= '0' && numStr[i] <= '9'){
phoneNum[j]=numStr[i];
j++;
}
}
}
code for phone_fmt.h
#include<stdio.h>
void phone_fmt(char *numStr, char *phoneNum);
Any help would be GREATLY appreciated.
Based on your logic, you need to create a char or int array to hold your 10 phone digit number as your first parameter in phone_fmt() function. The worked code is following.
#include <stdio.h>
void phone_fmt(int *digits, char *phoneNum){
sprintf(phoneNum, "(%d%d%d) %d%d%d-%d%d%d%d", digits[0],
digits[1],
digits[2],
digits[3],
digits[4],
digits[5],
digits[6],
digits[7],
digits[8],
digits[9]);
}
int main(){
char output[20];
int digits[10];
char c;
int i = 0, j = 0;
printf("Enter phone number string up to 200 characters: \n ");
while( (c = getchar()) != '\n' && i < 10 ){
if( (c >= '0' && c <= '9') ){
digits[i++] = (int)(c - '0');
}
++j;
}
if( j < 10 || j > 200 ){
printf("Invalid. Entry must be at least 10 characters and less then 200 characters.\n");
return -1;
}
if(i < 10){
printf("Invalid. Not enough digits to complete phone number.\n");
return -1;
}
phone_fmt(digits, output);
printf("Phone number: %s \n", output);
return 0;
}
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.
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;
}