I wrote this stupid chunk of code as an answer for a program exercise from the book "c programming a modern approach 2nd E." by K.N.King, namely ch7;ex4.
I couldn't make it does the same thing with less code, so, Can you?
It's just converting alphabetic phone numbers into numeric form, i'm really curious to see a better coding of this..
Thanks..
#include <stdio.h>
void main()
{
char c;
int phone_number;
printf("Enter phone number: ");
while((c = getchar()) != '\n') {
if(c == 'A' || c == 'B' || c == 'C')
printf("2");
if(c == 'D' || c == 'E' || c == 'F')
printf("3");
if(c == 'G' || c == 'H' || c == 'I')
printf("4");
if(c == 'J' || c == 'K' || c == 'L')
printf("5");
if(c == 'M' || c == 'N' || c == 'O')
printf("6");
if(c == 'P' || c == 'R' || c == 'S')
printf("7");
if(c == 'T' || c == 'U' || c == 'V')
printf("8");
if(c == 'W' || c == 'X' || c == 'Y')
printf("9");
if(c == '0')
printf("0");
if(c == '1')
printf("1");
if(c == '2')
printf("2");
if(c == '3')
printf("3");
if(c == '4')
printf("4");
if(c == '5')
printf("5");
if(c == '6')
printf("6");
if(c == '7')
printf("7");
if(c == '8')
printf("8");
if(c == '9')
printf("9");
if(c == '-')
printf("-");
}
printf("\n");
}
We can take advantage of the fact that characters are sequential (not sure if this is standard, but it happens in most representations, anyway)
Let's make a table specifying which number a letter represents. It would look something like
int keynum[26] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
keynum[0] is the number that A maps to, and so on. If we have a character c and we need to get the proper index in keynum we calculate it by c-'A'
Then our main loop would be:
while((c=getchar()) != '\n') {
if (c>='0' && c<='9')
putchar(c);
else if (c >= 'A' && c <= 'Z')
putchar('0' + keynum[c-'A'])
/* else error? */
}
2 + ((c-'A') / 3) (integral division) is the number you print for A-Y (if 'A'<=c && c<='O'!)
Related
I'm trying to solve a problem with replacing letters with numbers. The user will enter a string, in case there are letters, I must substitute the corresponding number, and in case there are * # - symbols, I must simply remove them.
However, I am facing an issue. When the user types only a numeric string, the last character of this string is being removed, which cannot happen. This can only happen if there are letters or symbols in the string.
Source
#include <stdio.h>
#include <string.h>
void alterChars(char phrase[])
{
int i, dashes = 0;
for (i = 0; phrase[i] != '\0'; i++)
{
if (phrase[i] == 'A' || phrase[i] == 'B' || phrase[i] == 'C')
{
phrase[i] = '2';
}
if (phrase[i] == 'D' || phrase[i] == 'E' || phrase[i] == 'F')
{
phrase[i] = '3';
}
if (phrase[i] == 'G' || phrase[i] == 'H' || phrase[i] == 'I')
{
phrase[i] = '4';
}
if (phrase[i] == 'J' || phrase[i] == 'K' || phrase[i] == 'L')
{
phrase[i] = '5';
}
if (phrase[i] == 'M' || phrase[i] == 'N' || phrase[i] == 'O')
{
phrase[i] = '6';
}
if (phrase[i] == 'P' || phrase[i] == 'Q' || phrase[i] == 'R' || phrase[i] == 'S')
{
phrase[i] = '7';
}
if (phrase[i] == 'T' || phrase[i] == 'U' || phrase[i] == 'V')
{
phrase[i] = '8';
}
if (phrase[i] == 'W' || phrase[i] == 'X' || phrase[i] == 'Y' || phrase[i] == 'Z')
{
phrase[i] = '9';
}
if (phrase[i] == '*' || phrase[i] == '#' || phrase[i] == '-')
{
dashes++;
}
else if (dashes > 0)
{
phrase[i - dashes] = phrase[i];
}
}
phrase[strlen(phrase)-1] = '\0';
printf("%s\n", phrase);
}
int main()
{
char phrase[300];
while (!feof(stdin))
{
scanf(" %[^\n]s", phrase);
alterChars(phrase);
}
return 0;
}
Any tips will be valuable. You can access the problem to see where the error is occurring. Anyway, it's on the last entry, at number 190. It is being printed 19, but in fact it should be printed 190, because the removal of characters should only occur when there are letters, or symbols.
Examples
Input: 333-PORTO
Output: 33376786
The problem:
Input: 190
Output: 19
With your "generous" scanning, i.e. practically no expected syntax, you can simply loop while scanning is successful.
while (1==scanf(" %299[^\n]", phrase)) alterChars(phrase);
That fixes the problem with your while condition ( see Why is “while ( !feof (file) )” always wrong? ).
Then you want to read each line until either newline or terminator:
for (i = 0; phrase[i] != '\0' && phrase[i] != '\n'; i++)
And you want to force-terminate with respect to the dashes.
phrase[strlen(phrase)-dashes] = '\0';
and you get the desired output - and in only one line.... ;-)
The explanation is, if you always terminate as with 1 dash, then it works for 1 dash, fails by cutting too much for zero dashes and does other unwanted stuff for more than one dash, i.e. repeat the last few characters.
It is after all unrelated to "numeric only".
I have incorporated this good input by chux:
scanf(" %[^\n]s" is bad as it has not width limit and 2) the s is pointless.
I am trying to take in 10 characters over a serial console and add them to an array called buffer. The first character needs to be 'L' or 'S' and the next characters either '1' or '0'.
The code passes the first if statement ok. But the line if((buffer[0] != 'L') || (buffer[0] != 'S')) doesn't seem to work even when I enter 'L' OR 'S'.
Is there anything wrong with using the buffer[0] != notation?
int main(void)
{
char ch;
char buffer[10] = "";
putstring("Enter 9 characters beginning with 'L' or 'S' and 8 digits\r\n");
for (int i = 0; i < 9; i++) {
ch = getcharacter();
if ((ch == '0') || (ch == '1') || (ch == 'L') || (ch == 'S')) {
buffer[i] = ch;
//check first character
if((buffer[0] != 'L') || (buffer[0] != 'S')) {
printf("First letter must be L or S\r\n");
goto error;
}
error:
return -1;
}
}
}
int getcharacter(void) {
char c = 0;
const uint32_t recieve_ready = 1 << 7;
//disable interrupt for a read ready
*uart_control_reg = 0;
while (1) {
//check if RRDY bit is set
if ((*uart_status_reg) & recieve_ready) {
c = *uart_rxdata_reg;
break;
}
}
return ((char) c);
}
if((buffer[0] != 'L') || (buffer[0] != 'S'))
is wrong, you need
if((buffer[0] != 'L') && (buffer[0] != 'S'))
or
if (!(buffer[0] == 'L' || buffer[0] == 'S'))
Your original code was "if the char is not L or the char is not S" which is always true. If the char is L, then the second part was true, making the whole if statement true.
Just noticed Chris Turner's comment above. The return -1 is always executed, move it to replace the line that says goto error.
Try using
if((buffer[0] != 'L') && (buffer[0] != 'S'))
instead of
if((buffer[0] != 'L') || (buffer[0] != 'S'))
Just some logic problem here. According to your code, the char needs to be equal to 'L' AND 'S' to avoid the condition, which is never the case !
Here i get the answers for vowels but not for continue it says error for the continue and also for break.
#include < stdio.h >
main() {
char c, d;
printf("say your word to find the vowels\n");
scanf("%c", & c);
if (c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 'u' || c == 'U')
printf("you got a vowel\n");
else
printf("cool no vowel word\n");
printf("continue\n");
printf("(y/n)\n");
scanf("%c", & d);
if (d == 'y' || d == 'Y')
continue;
else
break;
return 0;
}
if (d == 'y' || d == 'Y')
continue; // where?
else
break; // what?
You have nothing to continue or break in your main function.
Both continue and break only make sense within a loop, so you should add a while(true) loop around the code in main() to repeat the whole thing until the user decides to quit.
Continue and break works in the loop block.. but here you have not added them in loop. Put the whole if block in the while(1) and it will work
#include <stdio.h>
int main()
{
char c;
int d;
while (1) {
printf("say your word to find the vowels\n");
scanf("%c", &c);
if (c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 'u' || c == 'U')
printf("you got a vowel\n");
else
printf("cool no vowel word\n");
printf("To continue enter 1\n");
scanf("%d", &d);
if (d == 1)
continue;
else
break;
}
return 0;
}
Check the continue and break statement syntax in the following link.
https://www.codingunit.com/c-tutorial-for-loop-while-loop-break-and-continue
for example when I type in a string "Hello", when I press 'a' it should print "There are 2 vowels." Instead, it says there are 0. I'm new to programming and this is the first language I am learning. Help?
/*
Student: Josiah Eleazar T. Regencia
Course: BSIT 1
Subject: SCS 101
Professor: Daniel B. Garcia
Problem definition:
Write a menu program that will count the vowels and consonants in the string
*/
#include <stdio.h> //printf and scanf functions
#include <string.h> //string functions
#include <stdlib.h>
#include <conio.h>
#define PROMPT "Type in a word, a phrase, or a sentence." //instucts the user
/*
Declaring the function for the user's menu
*/
void menu();
/*
Declaration of function needed to count the vowels in the string
*/
int vowel_count(char *stringInput); //declaring the function to count the vowels sounds
/*
Declaration of function needed to count the consonants in the stringn
*/
int consonant_count(char *stringInput); //declaring the functions to count the consonant sounds
/*
Declaring the function needed to convert the streeting to uppercase
*/
int uppercase(char *stringInput);
/*
Declaring the function needed to convert the streeting to uppercase
*/
int lowercase(char *stringInput);
int main () {
char userInput[100]; // the string the user inputs
char commandKey[1]; //this key is for the menu
char newInput[100]; //this is for the new input to user will put in
int stringLength; //to identify the length of the string
/*
Variables for counting the vowels and consonants
*/
int consonantCount;
printf("%s\n\n", PROMPT); //instucts the user
gets(userInput);
stringLength = strlen(userInput); //gets the length of the string
//fgets(userInput, 100, stdin);
/*if(stringLength > 0 && userInput[stringLength - 1] == '\n') {
userInput[stringLength - 1] ='\0';
}*/
menu(); //prints out the menu for the user to pick his options
/*
The loop will run what the user asks the program to run while at the same time also asking
what the programmer wants next
*/
while(*commandKey != 'X' || *commandKey != 'x') {
//int commandLength; //length of the command key
printf("Enter your menu selection: ");
gets(commandKey);
/*commandLength = strlen(commandKey);
fgets(commandKey, 100, stdin);
if(commandLength > 0 && commandKey[commandLength - 1] == '\n') {
commandKey[commandLength - 1] ='\0';
}*/
if(*commandKey == 'A' || *commandKey == 'a') {
int vowelCount;
vowelCount = vowel_count(userInput);
printf("There are %d vowels.\n\n", vowelCount);
}
if(*commandKey == 'B' || *commandKey == 'b') {
consonantCount = consonant_count(userInput);
printf("There are %d consonants.\n\n", consonantCount);
}
if(*commandKey == 'C' || *commandKey == 'c') {
/*
This condition simply converts the input string to all lowercase letters
*/
lowercase(userInput);
}
if(*commandKey == 'D' || *commandKey == 'd') {
/*
This condition simply converts the input string to all lowercase letters
*/
uppercase(userInput);
}
if(*commandKey == 'E' || *commandKey == 'e') {
/*
Prints the current string
if the string was converted in lowercase letters, the outcome would be all lowercase letters
if the string was converted in uppercase letters, the outcome would be all uppercase letters
*/
printf("%s\n\n", userInput);
}
if(*commandKey == 'F' || *commandKey == 'f') {
/*
When the user wants to test a new string, this is the condition for the user
to automatically ask of it
*/
printf("%s\n", PROMPT);
gets(newInput);
strcpy(userInput, newInput);
}
if(*commandKey == 'M' || *commandKey =='m') {
/*
In case the user forgets, this will serve as a reminder of the menu
*/
menu();
}
if(*commandKey == 'X' || *commandKey == 'x') {
printf("Goodbye!\n");
break;
}
}
}
//Function that displays the menu.
void menu() {
/*
These are the set of command keys given to the user
*/
printf("\n\n\n");
printf("PRESS:\n\n");
printf(" A - Count the number of vowels in the string.\n");
printf(" B - Count the number of consonants in the string.\n");
printf(" C - Convert the string to uppercase.\n");
printf(" D - Convert the string to lowecase.\n");
printf(" E - Display the current string.\n");
printf(" F - Enter another string.\n");
printf("\n");
printf(" M - Display this menu.\n");
printf(" X - Exit the program.\n");
printf("\n\n");
}
/*
Defining the function for the vowel counting
*/
int vowel_count(char *stringInput) {
if ( *stringInput == '\0')
return 0;
else
return vowel_count(stringInput + 1) + (*stringInput == 'a' || *stringInput == 'A')
+ (*stringInput == 'e' || *stringInput == 'E')
+ (*stringInput == 'i' || *stringInput == 'I')
+ (*stringInput == 'o' || *stringInput == 'O')
+ (*stringInput == 'u' || *stringInput == 'U');
}
/*
Defining the function for the vowel counting
*/
int consonant_count(char *stringInput) {
if (*stringInput == '\0')
return 0;
else
return consonant_count(stringInput + 1) + (*stringInput == 'b' || *stringInput == 'B')
+ (*stringInput == 'c' || *stringInput == 'C')
+ (*stringInput == 'd' || *stringInput == 'D')
+ (*stringInput == 'f' || *stringInput == 'F')
+ (*stringInput == 'g' || *stringInput == 'G')
+ (*stringInput == 'h' || *stringInput == 'H')
+ (*stringInput == 'j' || *stringInput == 'J')
+ (*stringInput == 'k' || *stringInput == 'K')
+ (*stringInput == 'l' || *stringInput == 'L')
+ (*stringInput == 'm' || *stringInput == 'M')
+ (*stringInput == 'n' || *stringInput == 'N')
+ (*stringInput == 'p' || *stringInput == 'P')
+ (*stringInput == 'q' || *stringInput == 'Q')
+ (*stringInput == 'r' || *stringInput == 'R')
+ (*stringInput == 's' || *stringInput == 'S')
+ (*stringInput == 't' || *stringInput == 'T')
+ (*stringInput == 'v' || *stringInput == 'V')
+ (*stringInput == 'w' || *stringInput == 'W')
+ (*stringInput == 'x' || *stringInput == 'X')
+ (*stringInput == 'y' || *stringInput == 'Y')
+ (*stringInput == 'z' || *stringInput == 'Z');
}
/*
Defining the function for the conversion of the string to all uppercase letters
*/
int uppercase(char *stringInput) {
while(*stringInput) {
*stringInput = toupper(*stringInput);
stringInput++;
}
}
/*
Defining the function for the conversion of the string to all uppercase letters
*/
int lowercase(char *stringInput) {
while(*stringInput) {
*stringInput = tolower(*stringInput);
stringInput++;
}
}
This loop will never stop:
while(*commandKey != 'X' || *commandKey != 'x')
A loop stops when its condition is false. For *commandKey != 'X' || *commandKey != 'x' to be false, it is logically equivalent for *commandKey == 'X' && *commandKey == 'x' to be true, which doesn't quite work. *commandKey can't be both 'X' and 'x'.
Instead, you want:
while(*commandKey != 'X' && *commandKey != 'x')
Which will stop when *commandKey is 'X' or 'x'.
Also, you never initialized commandKey, so you can't test it in the loop (using values of uninitialized variables is undefined behavior). And if you want to treat it as a string, you need to declare it such that it holds at least 2 characters, because the null character is needed:
char commandKey[2] = { 0 };
This will initialize commandKey to an empty string. Remember that gets() will null-terminate the string, so, even if your command is just one key, gets() will need at least 2 positions to fill - the character command and the null terminating byte. Alternatively, you can leave commandKey as is (provided that you initialize it), and use getchar() instead, which reads one single character.
I have the following function
int namecomp(char c);
Part of the function code
else if (c == 'b' || 'B')
i=2;
The way I am calling it in main()
j= namecomp(s);
and s is defined as char s = 'B';
There is an error and whenever I am trying to use j the value is always 1 in the main. Please help me to know where exactly the error is. Thanks!
EDIT:Sorry Folks none of it worked., I am posting the complete code for help
int main (int argc, char* argv [])
{
int i;
int j;
char s = 'B';
j= namecomp(s);
printf ("%d",j);
}
int namecomp(char c)
{
int i;
if (c == 'a'||'A')
i=1;
else if ((c == 'b' || c == 'B'))
i=2;
return i;
}
c == 'b' || 'B'
always evaluates to 1, because it's parsed as
(c == 'b') || 'B'
I'm betting you want
(c == 'b') || (c == 'B')
This
(c == 'b' || 'B')
Should be:
(c == 'b' || c == 'B')
Otherwise, you're testing this:
((c == 'b') || 'B')
Which is the same as
((c == 'b') || true)
since 'B' is non-zero.
Remember that the logical and/or symbols can't be used inside a logical test, only to join logical tests together.
You wrote
(c == 'b' || 'B') // this can be ( (c=='b') || 'B') in your compiler
Did you mean
(c == ('b' || 'B'))
or
( (c == 'b') || (c=='B') )
you should use the latter.
You should approach these conditions as a paranoid with paranthesis to make sure it satisfies your conditions. Then you can try without paranthesis if it works for every condition.
c == 'b' || 'B' is always evaluate to 1 because 'B' is a nonzero value, so the second operand is always true.
You need to test your condition both.
if (c == 'b' || c == 'B')