I am in a chapter for control structures, i threw myself a while n case challenge but i can't seem to get it working, any heads up ?, i know my code is a bit dirty or alot dirty :D anyway the code is about asking a user for input on a color name then prints a corresponding color code, after that it asks if you want to continue if yes it continues if not it terminates.
#include <stdio.h>
main ()
{
char color[20];
char answer;
printf("Enter the color name: ");
scanf("%s", &color);
while (1) {
switch("color")
{
case "red":
printf("#FF0000\n");
break;
case "green":
printf("#00FF00\n");
break;
default:
printf("FFFFFF\n");
}
printf("Do you want to do that again(y/n): ");
scanf("%c", &answer);
if (answer == "y")
{
printf("Enter the color code: ");
scanf("%s",&color);
}
else
{
printf("Quiting.......\n");
break;
}
}
return 0;
}
There's more than one problem, but here's a few:
You're not comparing strings the right way. In C you can't use == to compare strings, you have to use strcmp (or strncmp).
You can't switch on a string in C. So you might want to replace the switch with if-else:
if (!strcmp(color, "red"))
/* ... */
else if (!strcmp(color, "green"))
/* ... */
else
/* "default" */
You're mixing different scanf strategies:
scanf("%s",&color); leaves \n in the input buffer
scanf("%c", &answer); reads that newline and stores it in answer
Basically the only good advice is: keep studying. You're not ready for this "challenge" yet.
Your switch statement always goes to default:. This is because you have the litaral "color" instead of the variable color.
You want
switch(color) {
but as pointed by others, that won't work either, because C switch doesn't allow strings.
You want to write:
switch (color)
{
...
}
but even that won't work since you need an integer expression; C does not handle string comparisons natively.
So, you'll either have to map the colour strings to integers, or forego a switch and use an `if / else if / else' chain:
if (strcmp(color, "red") == 0)
printf("#FF0000\n");
else if (strcmp(color, "green") == 0)
printf("#00FF00\n");
else
printf("FFFFFF\n");
To answer your question, you have to remember what is a string literal in C.
They are pointers to character arrays with string data embedded in the code by the compiler.
So, firstly, your switch statement uses a constant (address of "color" string) as a control variable.
Secondly, each case branch contains a meaningless address of a string as a label.
To emulate switch on strings in C, you have to use a sequence of if-else if with strcmp in conditions.
Related
I want the user to be able to input two types of input like: "C[some size_t]" and "O[some memory address]" and depending on whether it's a C or O at the beginning, I'll call different functions. I also want to be able to take in an unknown number of those inputs and in any order.
My way of going around it was something like this:
int main()
{
// variables
while (1) { // Infinite loop to take in multiple unknown amount of inputs?
while (fgets(input, BUFFER_SIZE, stdin)) {
if (sscanf(input, "%c%zu", &branch, &num) == 2) {
if (strcmp(&branch, "C")
// function call
} else if (sscanf(input, "%c%c", &branch, (char *)addr) == 2) {
if (strcmp(&branch, "O")
// function call
}
}
}
return 0;
}
I understand why it's not working of course and I know my not-solution is wrong but I have no idea how else to go about this. The code takes in the first input and just hangs and if I start with an input beginning with O, it'll go into the first if statement when it's not supposed to. I'm also not sure if my while(1) loop is the correct way to deal with multiple user inputs.
You try to read the branch char and the respective argument in one single go – however the argument differs in both cases. So you need first to read the character, then decide and only then scan the argument – as soon as you know what to scan at all and thus are able to select the appropriate format string.
As you just read in any character you could do so a bit simpler with getc, by the way:
char branch = getc(); // instead of `if(scanf("%c", &branch) == 1)`
// note: would have been one single scan (branch) only!
if(branch == 'C')
{
// scan num
}
else if(branch == 'O')
{
// scan addr
}
else
{
// error handling
}
or alternatively (I personally would prefer)
char branch = getc();
switch(branch)
{
case 'C':
// scan num
break;
case 'O':
// scan addr
break;
default:
// error handling
break;
}
Note that strcmp requires null-terminated strings (char arrays) and cannot be used for comparing single characters – these need to be compared via equality operator, see above.
I am working on this C code and I am confused why this is not working. I have looked at other questions here for comparing 2 chars and I have done it the exact same way but for some reason it isn't working.
What happens when it runs is that it will work for t and o, but not for c, even though I have implemented them all the same way.
Split_string was provided to us (no bugs) and returns the number of words in the string inputted via the keyboard. It also takes in an array of strings and puts each word at a different index.
Any suggestions would be greatly appreciated
char input[100];
printf("What commmand would you like to use? t, o, or c\n");
while(fgets(input, 100, stdin)!=NULL){
char ** ptr = malloc(sizeof(char*)*10);
int wordno = split_string(input, ptr);
if((*ptr[0]=='t') && wordno==1) {
text(root_ptr);
} else if(*ptr[0]=='t' && wordno>1){
printf("No arguments for function t\n");
} else if(*ptr[0]='o' && wordno==9){
open(root_ptr);
} else if(*ptr[0]=='o' && wordno != 9){
printf("Need 8 attributes to open o\n");
} else if(*ptr[0]=='c' && wordno==2){
open(root_ptr);
} else if(*ptr[0]=='c' && wordno !=2){
printf("Only need 2 arguments to copy\n");
} else {
printf("Please enter a value command\n");
}
printf("Enter t to text, o to open or c to copy\n");
}
Check the following line. There is a = missing, so you actually assign o to the first element of your array instead of comparing with o. Afterward, it can never be c.
} else if(*ptr[0]='o' && wordno==9){
The error is here:
else if(*ptr[0]='o' && wordno==9){
where you force the first character to be 'o'. For that reason I usually write comparisons in the Yoda form:
if (('o' == (*ptr[0])) ...
even if it at first it looked awkward and is overkill. If an equal sign you forget, an error the compiler will throw.
However, this kind of behaviour should have been caught by activating the full warnings on the compiler. I strongly suggest you to keep them on at all times.
Also, you allocate the memory again at each cycle, causing a leak (this won't bite you very soon, if at all, but still):
char ** ptr = malloc(sizeof(char*)*10);
Finally, you might be better served by a switch statement:
switch(*ptr[0]) {
case 't':
...
break;
...
default:
printf("Huh?\n");
break;
}
I have this code sample. There is a scanf to hold the input String values from keyboard (i.e Lotus). But even if I type the word Lotus correctly It does not execute the relevant if statement. **Is there any problem with my scanf function???
#include<stdio.h>
int main()
{
char landType,houseType[100],wantToContinue,wantToContinue2;
float installment;
wantToContinue='Y';
while(wantToContinue == 'Y' || wantToContinue == 'y') {
printf("Land Type : ");
scanf(" %c",&landType);
if(landType == 'A') {
printf("Type of House: ");
scanf(" %s", houseType);
if(houseType == "Lotus") {
//this won't go inside if statement even if I type Lotus correctly
installment=4000000-500000;
printf("Monthly Installment : R.s %.2f\n",installment/120);
printf("Do you want to Continue?(Y/y or N/n) : ");
scanf(" %c",&wantToContinue2);
if(wantToContinue2 == 'Y' || wantToContinue2 == 'y') {
wantToContinue=wantToContinue2;
printf("\n");
}else{
wantToContinue='N';
}
}
}
}
}
Be careful when comparing two strings in C. You should use the strcmp function from the string.h library, like so:
if(strcmp("Lotus", houseType) == 0)
When you write if(houseType=="Lotus") you are actually comparing the base address of the two strings and not their actual content.
In C, strings cannot be compared using ==. This is because strings are not a basic data type in C, that is C does not inherently understand how to compare them - you must use a function instead.
A standard function for comparing strings in C is strcmp(), e.g.:
if (strcmp(houseType, "Lotus") == 0)
{
// do some work if the strings are equal
}
To explain further, your initial attempt to compare strings using housetype == "Lotus" actually compares the address where the first character of the character array houseType is stored with the address where the first character of the character array "Lotus" is stored.
This happens because strings in C are just arrays of characters - they are not an inherent data type, C does not, as such, understand the difference between an array of integers and an array of characters, they are all just numbers arranged contiguously somewhere in memory and it treats them as such unless you specifically use code that operates on them as strings instead.
I'm stuck in a problem given in a book. The problem is -
The prototypical Internet newbie is a fellow name B1FF,who has a unique way of wriring messages.Here’s a typical B1FF communique.:
H3Y DUD3, C 15 R1LLY C00L
Write a “B1FF filter” that reads a message entered by the user and translates it into B1FF-speak:
Enter message: Hey dude, C is rilly cool
In B1FF-speak : H3Y DUD3, C 15 R1LLY C00L
Your program should convert the message to upper-case letters,substitute digits for certain letters (A=4,B=8,E=3,I=1,O=0,S=5).
My Program-
#include<stdio.h>
int main()
{
char arr[50]={0},ch[50]={0};
int i=0;
printf("\nenter the sentence : ");
while(arr[i-1]!='\n')
{
scanf("%c",&arr[i]);
i++;
}
i=0;
while(arr[i]!='\n')
{
if(arr[i]=='e')
ch[i]='3';
if(arr[i]==('A'||'a') )
ch[i]='4';
if(arr[i]==('B'||'b'))
ch[i]='8';
if(arr[i]==('I'||'i'))
ch[i]='1';
if(arr[i]==('o'||'O'))
ch[i]='0';
if(arr[i]==('S'||'s'))
ch[i]='5';
else ch[i]=arr[i]-32;
i++;
}
ch[i]='\n';
i=0;
printf("\nIn B1FF-SPEAK : ");
while(ch[i]!='\n')
{
printf("%c",ch[i]);
i++;
}
printf("\n");
return 0;
}
OUTPUT OF THE PROGRAM-
I don't understand why the program is not converting the alphabets and why scanf() is not accepting space as a character ?
First and foremost, you cannot chain the logical OR operator like
if(arr[i]==('A'||'a') )
and get what you're expecting, because this resolves to an always TRUE condition. [('A'||'a') evaluates to TRUE]
You have to use
if ( (arr[i]=='A') || (arr[i] =='a'))
That said,
ch[i]=='8';, ch[i]==1; are basically empty statements. You're comparing and discarding the comparison result. If you want assignment, you need to use =.
the else ch[i]=arr[i]-32; only binds with the previous if statement, no the whole if chains. You can either make use of switch case or if-else if-else constructs to take care of that part.
you did not handle whitespaces separately.
To elaborate, due to the second point above, you code basically reduces to
while(arr[i]!='\n')
{
if(arr[i]==('S'||'s')) //always false
ch[i]='5';
else ch[i]=arr[i]-32; //always TRUE
i++;
}
which is just a poor attempt to convert lowercase to UPPERCASE. In case a non-alpha input is there in the string, the code will blow up.
That said, regarding the
why scanf() is not accepting space as a character?
part, scanf() perfectly accepts a space as an input with %c, it's you just convert it no NUL (null) by blindly subtracting 32 from a space which has an ASCII value of decimal 32. A NUL is non printable, and does not appear in the output.
Some recommendations:
Don't use lots of little calls to scanf("%c"...). Use fgets() (manpage). fgets reads in a whole line from input, stores it in your buffer (including the newline), and sticks a '\0' byte at the end of it so you know how long the string is.
use toupper() (manpage). It takes an arbitrary character as input. If the input is a lower case letter, then the output is the upper-case version of that letter. Otherwise, the output is the same as the input.
Update the array in-place. You don't need two arrays. Read the array with fgets(), loop over it with your translation logic, updating each character as you go, then write the array out with fputs().
Learn about switch statements. A switch statement will make your code more compact and easier to read. You need one case for every letter->number transform, and a default case for everything else.
c = toUpper(c);
switch (c) {
case 'A': c = '4'; break;
case 'B': c = '8'; break;
....
default: break;
}
So basically I wanted to create a program in C, in wich you would input 2 character long string (mix of letter and noumber ex.r1,u2,i3,i4,r6) to be the input in my program. Later I want to put this string in SWITCH. Is this possible?
Here's my simple sourcecode. Please correct me on any mistakes :)
#include <stdio.h>
int main(void)
{
char string[2];
scanf("%s", &string);
switch (string)
{
case 'u1' :printf("%s\n", string);break;
default :printf("ERROR");break;
}
return 0;
}
Create a code based on the string and switch on that.
#define Code(a,b) (a + 256*b)
char string[3]; // 3 not 2
if (scanf("%2s", string) != 1) { // No &
Handle_Error();
}
int scode = Code(string[0], string[1]);
switch (scode) {
case Code('u', '1') : printf("%s\n", string); break;
case Code('r', '2') : printf("r2\n"); break;
...
default :printf("ERROR");break;
}
A switch(x) needs an integer value for x and string is an array. So the original approach will not work.
The program can use an integer based on the string for x and use the same method for generating the case values. Since there is only the first 2 char of the string are of interest, the int value is unique.
No, this is not possible. Switch only works with integral types in C (int, short, long, etc, as well as types defined with enum).
You can however use a simple if-else construct to get the same behavior:
if (strcmp(string, "ui" ) == 0) //test for string equality
{
printf("%s\n", string);
}
else
{
printf("ERROR")
}
We use strcmp instead of == because we are dealing pointers which almost certainly not compare equal even when the two strings have the same content.
strcmp(str1, str2) == 0 is the standard idoim in C for comparing two strings.
strcmp returns an integer representing how two strings compare to each other. 0 means they are equal, a negative number means that the first string is lexographically "less than" the second, and a positive number means that the first string is lexographically "greater than" the second. More info can be found here.
A switch won't work here.
You need to use an if/else if construct and strcmp to compare the strings.
Also, you need at least 3 characters in your input array so that it can hold the two input characters and the terminating null character.
Of course, such a small buffer can easily overflow.