Why does getchar() read an entire line? - c

The sample of the program is as follow:
int main(void)
{
char input;
printf("\nEnter phone number: ");
while ((input = getchar()) != '\n') {
switch (toupper(input)) {
case 'A': case 'B': case 'C':
printf("2");
break;
case 'D': case 'E': case 'F':
printf("3");
break;
case 'G': case 'H': case 'I':
printf("4");
break;
case 'J': case 'K': case 'L':
printf("5");
break;
case 'M': case 'N': case 'O':
printf("6");
break;
case 'P': case 'R': case 'S':
printf("7");
break;
case 'T': case 'U': case 'V':
printf("8");
break;
case 'W': case 'X': case 'Y':
printf("9");
break;
default:
putchar(input);
}
}
printf("\n\n");
return 0;
}
My question is, how on Earth does the flow here work? I can't seem to understand the path the program took. Does the char variable magically become an array? How is it that putchar() prints the entire line instead of the first character entered? How exactly does something that's supposed to get and print one character, reads and prints an entire line of characters while altering them with the switch statement? Does it test each char as its entered? But then how is the string printed as a string?
Edit: I've done some research and I read about a keyboard buffer, which seems to be the cause of my confusion. To my knowledge, getchar() and putchar() receives and outputs a single character. I'm aware that the loop asks continuously for the next "buffered" char when the getchar() comes back around, still a bit confused by I should get it, but what's more confusing is putchar(). At the end of the loop, when it breaks and goes to the condition, does it print that one character then continues and prints the other one by one with each execution of the loop? Only stopping the loop at which point the new line was read? And if so, only what was previously printed, is displayed on the screen? And then if that's the case then the printed chars would print in line next to each other with each execution, giving the illusion of a string? I need confirmation on this and also, when is the char discarded and replaced? After its printed? And at which line does it receive the next char in the buffer queue?

Related

Multiple chars in SWITCH CASE in C

I have a school project and I'm working on a menu where the users chooses what he wants to do. I want the choice variable to be a char, not an int. Can I add multiple chars in a single switch case? I searched for a solution but I only found one when the value is an int, not a char. I tried this but it didn't work:
char choice;
scanf("%c", &choice);
switch(choice)
{
case 'S', 's':
// do something
break;
case 'I', 'i':
// do another thing
break;
default:
printf("\nUnknown choice!");
break;
}
For starters use the following format in scanf
char choice;
scanf( " %c", &choice );
^^^
(see the blank before the conversion specifier). Otherwise the function will also read white space characters.
You can use several adjacent case labels like for example
switch(choice)
{
case 'S':
case 's':
//do something
break;
case 'I':
case 'i':
//do anotherthing
break;
default:
printf("\n Unknown choice !");
break;
}
An alternative approach is to convert the entered character to the upper case before the switch. For example
#include <ctype.h>
//...
char choice;
scanf( " %c",&choice );
switch( toupper( ( unsigned char )choice ) )
{
case 'S':
//do something
break;
case 'I':
//do anotherthing
break;
default:
printf("\n Unknown choice !");
break;
}
You can use fall through like this:
case 'S':
case 's':
// do something
break;
case ...
You can put multiple case labels after each other:
switch(choice) {
case 'S':
case 's':
//do something
break;
case 'I':
case 'i':
//do anotherthing
break;
default:
printf("\n Unknown choice !");
break;
}

Program that keeps running until the user inputs n to exit

I a working on an assignment that allows the user to input "type" and "weight" and it'll display the cost. Here is the code. I want it to keep running until the user enters 'n'.
main()
{
char type,chr;
float cost,weight;
do
{
printf("Insert the type of fish: "); /*inputs type and weight*/
scanf("%c",&type);
printf("insert weight: ");
scanf("%f",&weight);
switch(type)
{
case 'K':
case 'k':
cost=weight*9.00;
break;
case 'R':
case 'r':
cost=weight*10.00;
break;
case 'S':
case 's':
cost=weight*12.00;
break;
case 'G':
case 'g':
cost=weight*8.00;
break;
case 'T':
case 't':
cost=weight*15.00;
break;
default :
printf("Invalid type\n");
}
printf("The cost of fish is:%.2f \n",cost);
printf("Do you want to continue?Y/N: ");
scanf(" %c",&chr);
}
while(chr == 'Y' || chr == 'y');
}
I have used the do..while loop, it worked fine until I typed in 'y' and I cannot enter the type.
Reading types from the stdin stream assumes you know exactly what is next in the stream. As Streeragh mentions, you likely have a newline as the next input character. You can triage this by dumping out what chr is (try it in hex, like %0x). The mentioned article also offers good advice: Input the text as %s (or use readline) and then parse out the input. Look into strtok. And also be aware that stdin can be redirected from a pipe (i.e out.exe < sampleinput.txt) Cheers.

Switch / Case issue

For C language, I know I'm close, but for for any character inputted, the printout is "Consonant". What is wrong with my switch case statement. Will I need if statements?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char name;
printf("Enter a character: ");
scanf_s("%c", &name);
switch (name)
{
case 'a':
printf("Vowel");
break;
case 'e':
printf("Vowel");
break;
case 'i':
printf("Vowel");
break;
case 'o':
printf("Vowel");
break;
case'u':
printf("Vowel");
break;
case 'y':
printf("Sometimes");
break;
default:
printf("Consonant");
}
return 0;
}
Note that the Microsoft page for scanf_s() says:
In the case of characters, a single character may be read as follows:
char c;
scanf_s("%c", &c, 1);
Your scanf_s() call is failing, but you are not checking the result, so you don't know that.
ALWAYS check the result of input functions!
And make sure you've read the manual page for functions you're using.
It's probably also a good idea to use " %c" as the format string to skip white space. However, that's a refinement for later.
You don't have a break; after the code in the default: case label. That's not a good idea.
You can use:
if (scanf_s("%c", &name, 1) == 1)
{
switch (name)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("Vowel\n");
break;
case 'y':
printf("Sometimes\n");
break;
default:
printf("Consonant\n");
break;
}
}
else
fprintf(stderr, "Failed to read a character\n");
Note that all upper-case letters, punctuation, white space and control characters are deemed to be consonants. That's not entirely accurate.

How to convert hex value to binary value in C

Can someone please help me fix my code.I have a text file with hexadecimal values. Now I need to convert the hexadecimal value to binary and print it. This is my code so far:
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000
int hex_to_binary(char *argv[])
int main(int argc,char *argv[])
{
FILE *file;
file = fopen(argv[1],"r");
char line[100];
while(!feof(file)){
fgets(line,100,file);
hex_to_binary(line);
}
fclose(file);
return 0;
}
int hex_to_binary(char *argv[]){
char binaryNumber[MAX],hexaDecimal[MAX];
long int i=0;
scanf(“%s”,argv[1]);
printf("\nEquivalent binary value: ");
while(hexaDecimal[i]){
switch(hexaDecimal[i]){
case '0': printf("0000"); break;
case '1': printf("0001"); break;
case '2': printf("0010"); break;
case '3': printf("0011"); break;
case '4': printf("0100"); break;
case '5': printf("0101"); break;
case '6': printf("0110"); break;
case '7': printf("0111"); break;
case '8': printf("1000"); break;
case '9': printf("1001"); break;
case 'A': printf("1010"); break;
case 'B': printf("1011"); break;
case 'C': printf("1100"); break;
case 'D': printf("1101"); break;
case 'E': printf("1110"); break;
case 'F': printf("1111"); break;
case 'a': printf("1010"); break;
case 'b': printf("1011"); break;
case 'c': printf("1100"); break;
case 'd': printf("1101"); break;
case 'e': printf("1110"); break;
case 'f': printf("1111"); break;
default: printf("\nInvalid hexadecimal digit %c ",hexaDecimal[i]); return 0;
}
i++;
}
return 0;
}
I keep getting errors such as:
part1_V2.c: In function ‘hex_to_binary’:
part1_V2.c:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
part1_V2.c:22: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
part1_V2.c:26: error: stray ‘\342’ in program
part1_V2.c:26: error: stray ‘\200’ in program
part1_V2.c:26: error: stray ‘\234’ in program
part1_V2.c:26: error: stray ‘\342’ in program
part1_V2.c:26: error: stray ‘\200’ in program
part1_V2.c:26: error: stray ‘\235’ in program
part1_V2.c:59: error: expected ‘{’ at end of input
Thanks in advance!
Ok guys thanks for your help I got my code working but now I'm have trouble with the output:
The textfile I pass to the main function contains:
"1283" (line1)
"5105" (next line)
These are the hex values on the file. So when I run the program I get output:
Equivalent binary value: 0001001010000011
nvalid hexadecimal digit
Invalid hexadecimal digit
Equivalent binary value: 0101000100000101
I'm wondering why I'm getting the invalid hexadecimal digit output? Is it because it is trying to convert "\n" or empty space to binary?
It seems like there are a couple of non-ascii characters in your code, e.g. “ and ”, which should be ".
What's left are syntax and type errors.
There are some syntax errors in your code. Try this modified code. If you are passing right parameters to main() than it should work:
#include <stdio.h>
int hex_to_binary(char*);
int main(int argc, char *argv[])
{
FILE *file;
file = fopen(argv[1],"r");
char line[100];
while(!feof(file)){
fgets(line,100,file);
hex_to_binary(line);
}
fclose(file);
getchar();
return 0;
}
int hex_to_binary(char* hex_string)
{
int i=0;
printf("\nEquivalent binary value: ");
while(hex_string[i])
{
switch(hex_string[i])
{
case '0': printf("0000"); break;
case '1': printf("0001"); break;
case '2': printf("0010"); break;
case '3': printf("0011"); break;
case '4': printf("0100"); break;
case '5': printf("0101"); break;
case '6': printf("0110"); break;
case '7': printf("0111"); break;
case '8': printf("1000"); break;
case '9': printf("1001"); break;
case 'A': printf("1010"); break;
case 'B': printf("1011"); break;
case 'C': printf("1100"); break;
case 'D': printf("1101"); break;
case 'E': printf("1110"); break;
case 'F': printf("1111"); break;
case 'a': printf("1010"); break;
case 'b': printf("1011"); break;
case 'c': printf("1100"); break;
case 'd': printf("1101"); break;
case 'e': printf("1110"); break;
case 'f': printf("1111"); break;
default: printf("\nInvalid hexadecimal digit %c ", hex_string[i]);
}
i++;
}
return 0;
}
you first minor error is at function definition at line 5. Add a semicolon on the end:
int hex_to_binary(char *argv[]);
Also there in no use for it, so delete the line:
scanf(“%s”,argv[1]);
And rewrite the while loop:
while(hexaDecimal[i]!='\n' && hexaDecimal[i]!='\0')
{
switch(hexaDecimal[i])
{
...
}
i++;
}
Note thet i++ is within the loop. Plus the return 0 statement on the end is outside any function. Move it in.
Hope this helps!
As mentioned in the comments you are missing a ; on line 5.
Missing a ; can cause a cascade of errors, due to the compiler looking for something to end the statement (which wasn't ended by the ;).
I'm going to go into teacher mode so I apologise in advance if I come across as condescending.
Bearing that in mind, attempt to fix each error in turn. The error messages always look really technical, but if you stop and read it it gives a lot of information.
So for your first error, on line 8, it's stating that it was expecting something be the {. Since this is the start of the main function, the contents of lines 7-8 are correct, so the error must be before these two lines.
Before your main function is a function prototype, which...aha...is missing the semicolon.
In regards to the errors saying stray \xxx in program, this is likely because you've copied the scanf("%s", argv[1]) line from a word document or website, and it's copied a formatted pair of quote marks.
To fix, just delete the quotes and type them by hand.

Command Line Menu in C

I'm trying to implement a command line menu in C so that when the user enters a character, it will instantly process the character and carry out specific functions. The problem is, whenever I try to make it so that after each input is processed, the menu displays again and is ready for new input, the program will just continually read input and never process it unless I exit the program.
This is the code that works 1 time through:
char command;
command = getchar();
switch(command){
case 'c':
//create a new hash table;
break;
case 'l':
//look up a word;
break;
case 'f':
//read a file
break;
case 'p':
//print the table;
break;
case 'r':
//Remove a word
break;
case 'q':
exit(0);
break;
}
However, if I try to place it into an infinite loop to continually run, like I said, it will never process the inputs until I exit the program.
This code should work for you — it works for me. Note the use of int for the variable command.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
int command;
while ((command = getchar()) != EOF)
{
switch(command)
{
case 'c':
printf("Create a new hash table\n");
break;
case 'l':
printf("Look up a word\n");
break;
case 'f':
printf("Read a file\n");
break;
case 'p':
printf("Print the table\n");
break;
case 'r':
printf("Remove a word\n");
break;
case 'q':
printf("Quit\n");
exit(0);
break;
default:
printf("Unexpected input %d (0x%.2X) ('%c')\n",
command, command, isgraph(command) ? command : '.');
break;
}
}
return 0;
}

Resources