Handling inputs for int, char, float - c

I am trying to write a program that loops asking the user to continuously input either a float, int, or char and echo it back to them until they enter 'q', then the loop ends. I do not understand how to decipher between an int, char, or float before entering the loop. I have tried if (scanf("%c", ch)) and so on for float and int and that works great, but once I added the loop in it's messing me up. I have tried several different combinations, but I have still not found my answer.
Here is one attempt to show you exactly what I am trying to do:
char ch;
int num = 0;
float fl = 0;
printf("Enter a value: ");
while(ch != 'q') {
if (scanf("%c", &ch) && !isdigit(ch)) {
printf("You entered a character %c\n", ch);
}
else if (scanf("%d", &num)) }
printf("You entered an integer %d\n", num);
}
else if (scanf("%d", &num)) {
printf("You entered a floating point number %f\n", fl);
}
printf("Enter another value: ");
}
}
This keeps doing something strange and I cannot pinpoint my problem. Thank you in advance!

You cannot accomplish that with your approach. You can scan a line and parse it accordingly:
char line[128]; /* Create a buffer to store the line */
char ch = 0;
int num;
float fl; /* Variables to store data in */
int r;
size_t n; /* For checking from `sscanf` */
/* A `do...while` loop is best for your case */
do {
printf("Enter a value: ");
if(fgets(line, sizeof(line), stdin) == NULL) /* If scanning a line failed */
{
fputs("`fgets` failed", stderr);
exit(1); /* Exits the program with a return value `1`; Requires `stdlib.h` */
}
line[strcspn(line, "\n")] = '\0'; /* Replace `\n` with `'\0'` */
r = sscanf(buffer, "%d%zn", &num, &n);
if(r == 1 && n == strlen(line)) { /* If true, entered data is an integer; `strlen` requires `string.h` */
printf("You entered an integer %d\n", num);
}
else{
r = sscanf(buffer, "%f%zn", &fl, &n);
if(r == 1 && n == strlen(line)) { /* If true, entered data is a float; `strlen` requires `string.h` */
printf("You entered a floating point number %f\n", fl);
}
else{
if(strlen(line) == 1) /* If true, entered data is a character; `strlen` requires `string.h` */
{
ch = line[0];
printf("You entered a character %c\n", ch);
}
else{ /* Entered data is something else */
printf("You entered \"%s\"\n", line);
}
}
}
}while(c != 'q');
Disclaimer: I wrote the above code using a mobile and I haven't tested it.
Update (did not test and wrote with my mobile):
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void)
{
int c = 0;
bool random = false;
bool flag = true;
bool is_float = false, is_char = false, is_number = false;
do{
c = getchar();
if(c == EOF)
break;
if(!random)
{
if(isdigit(c))
{
is_number = true;
}
else if(c == '.')
{
if(is_number)
{
if(is_float)
{
random = true;
}
else
{
is_float = true;
}
}
else if(!is_number && !is_float && !is_char)
{
is_float = true;
}
}
else if(c == '-' && !is_float && !is_number && !is_char);
else if(isalpha(c))
{
if(is_char)
random = true;
else
{
is_char = true;
if(c == 'q')
flag = false;
}
}
else
{
random = true;
}
if((is_char && is_float) || (is_char && is_number))
random = true;
if(c == '\n' && !is_char && !is_float && !is_number)
random = true;
}
if(c == '\n')
{
if(random)
/* puts("You entered a random string!"); */
puts("Invalid input!");
else if(is_float)
puts("You entered a float!");
else if(is_number)
puts("You entered a number!");
else if(is_char)
puts("You entered a character!");
else
puts("Error!");
if(!flag && !is_number && !is_float && !random)
flag = false;
else
flag = true;
is_char = is_float = is_number = random = false;
}
}while(flag);
puts("Done");
return 0;
}

Related

Repeating error message when trying to receive an integer in a specific range

The function below receives a range and then asks for an integer. It then must test to make sure it is in that range and is not a char. However, whenever I input any letters it just loops the "ERROR: Value must be between %d and %d inclusive: " msg.
void clearStandardInputBuffer(void)//clears character
{
while (getchar() != '\n')
{
;
}
}
int getIntFromRange(int lowbound, int upperbound)
{
int rangenum;
char newline = 'x';
while (1)
{
scanf(" %d%c", &rangenum, &newline);
if (rangenum <= upperbound && rangenum >= lowbound && newline == '\n')
{
return rangenum;
}
else
{
if (rangenum > upperbound || rangenum < lowbound)
{
printf("ERROR: Value must be between %d and %d inclusive: ", lowbound,upperbound);
}
else if (newline != '\n') {
clearStandardInputBuffer();
printf("ERROR: Value must be an integer: ");
}
}
}
return 0;
}
int main(void)
{
getIntFromRange(0, 1);
}
Looking for any help!

C programm to read characters between two '*'

I want the programm to read the characters that are between two stars and if there are not two stars, it must print a respective message. For example if the input is 1abc*D2Efg_#!*34567, the output is between first tow stars (letters : 4, digits:1, other:3) any help will be appreciated
int main()
{
int ch,lowercase_lett,digits,other,uppercase_lett,asterisk;
lowercase_lett = 0;
uppercase_lett = 0;
digits = 0;
other = 0;
asterisk = 0;
printf("enter characters : ");
while((ch = getchar()) != '\n' && ch != EOF)
{
if(ch == '*')
{
asterisk++;
}
if(asterisk < 2)
{
printf("\ntwo asterisks not found\n");
}
else
{
if(ch>='a' && ch <= 'z')
{
lowercase_lett++;
}
else if(ch>='A' && ch <= 'Z')
{
uppercase_lett++;
}
else if(ch >='0' && ch <= '9')
{
digits++;
}
else
{
other++;
}
}
}
printf("\n%d letters %d digits and %d other" , lowercase_lett+uppercase_lett,digits,other);
return 0;
}
Count characters when exactly one asterisk has been found. Functions in ctype.h are useful to determine the type of characters.
#include <stdio.h>
#include <ctype.h>
int main(void){
int ch,lowercase_lett,digits,other,uppercase_lett,asterisk;
lowercase_lett = 0;
uppercase_lett = 0;
digits = 0;
other = 0;
asterisk = 0;
printf("enter characters : ");
while((ch = getchar()) != '\n' && ch != EOF)
{
if(ch == '*')
{
asterisk++;
if(asterisk>=2)
{
break;
}
}
else if(asterisk==1)
{
if(islower(ch))
{
lowercase_lett++;
}
else if(isupper(ch))
{
uppercase_lett++;
}else if(isdigit(ch)){
digits++;
}else{
other++;
}
}
}
if(asterisk<2)
{
printf("\ntwo asterisks not found\n");
}
else
{
printf("\n%d letters %d digits and %d other" , lowercase_lett+uppercase_lett,digits,other);
}
return 0;
}
You were almost there, but your code contains some lines in wrong places.
Look at my solution. I just tested and it works for your problem:
#include <stdio.h>
int main(){
int ch;
int lowercase_lett = 0;
int uppercase_lett = 0;
int digits = 0;
int other = 0;
int asterisks = 0;
printf("Enter characters: ");
while((ch = getchar()) != '\n' && ch != EOF)
{
if(asterisks == 2){
break; //End the search
}
else if(ch == '*'){
asterisks++; //Increment until we have 2 *
}
else if(asterisks == 1){
if((ch >= 'a') && (ch <= 'z')){
lowercase_lett++;
}
else if((ch >='A') && (ch <= 'Z')){
uppercase_lett++;
}
else if((ch >= '0') && (ch <= '9')){
digits++;
}
else{
other++;
}
}
}
if (asterisks >= 2){
printf("\n%d letters %d digits and %d other" , lowercase_lett+uppercase_lett,digits,other);
}
else{
printf("\ntwo asterisks not found\n");
}
return 0;
}

How to re-ask for user input if user inputted a non-integer

How do I keep re-asking the user to enter a valid input that is an integer? I know how to validate an integer range input, but I don't know how to validate a non-integer input when prompted to enter an integer in C.
#include <stdio.h>
int main() {
int menu;
while(true) {
printf("Choose a menu (1-4):\n");
do {
scanf("%d", &menu);
} while(menu < 1 || menu > 4);
if(menu == 1) {
printf("menu 1\n");
} else if(menu == 2) {
printf("menu 2\n");
} else if(menu == 3) {
printf("menu 3\n");
} else if(menu == 4) {
printf("menu 4, exit\n");
break;
}
}
return 0;
}
Any help would be appreciated, I'm sorry if this is a duplicate as everytime I try to search the solution, it's on another language or the thread is asking "how to validate integer input range" instead of non-integer input.
if you want to know when the user has given a non-integer input, a way of doing that is as follows:
char number; /* assuming you'll only need numbers 0-9 */
int menu;
while (true)
{
scanf("%c",&number);
if (number >= '0' && number <= '9')
break;
else
printf("The input is not an integer\n");
}
menu = number - '0' ;
/* write rest of the code here */
If the input is 1 - 999, you can use this:
char *s = malloc(sizeof(char)*4);
while (true)
{
scanf("%s", s);
is_int = true;
menu = 0;
if (s[3] != '\0')
{
printf("integer bigger than 999 not allowed, input again\n");
continue;
}
for (int itr = 0; s[itr] != '\0'; itr++)
if (s[itr] >= '0' && s[itr] <= '9')
{
menu = menu*10 + s[itr]-'0';
}
else
{
is_int = false;
printf("not a valid integer, input again\n");
break;
}
if (is_int && menu != 0)
break;
}
Separate input from parsing.
Consider a helper function. Use fgets() to read, then parse.
// return 0 on success, EOF on end of file
int read_int(const char *prompt, int min, int max, &val) {
#define LINE_N 100
while (1) {
fputs(prompt, stdout);
fflush(stdout);
char buf[LINE_N];
if (fgets(buf, sizeof buf, stdin) == NULL) {
return EOF;
}
char *endptr;
errno = 0;
long val = strtol(buf, &endptr, 0);
// Validate an integer was read and if it is in range
if (endptr > buf && errno==0 && val >= min && val <= max) {
return (int) val;
}
}
}
Usage
int menu;
if (get_int("Choose a menu (1-4):\n", 1, 4, &menu) == EOF) {
printf("Input closed\n");
return 0;
}
if(menu == 1) {
...

How would i make this program loop the main twice?

I need my program to create two different text files (midinotes1 & midinotes2) and store two bits of data inside them to be read later on. is there an efficient way without copying the code? i understand i need to have filepointer1 writing to midinotes1 and filepointer2 writing to midinotes2 but i dont know how to make my program do that?
Thanks for any advice!
#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
float mtof(int note, float frequency);
int main()
{
FILE *textFilePointer;
FILE *textFilePointer2;
int note;
int velocity;
int program;
int counter = 0;
char user;
float frequency;
do
{
printf("Press R to Record (R) or (X) to Exit: \n");
scanf(" %c", &user);
if (user == 'r' || user == 'R')
{
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
counter = 0;
if (textFilePointer == NULL)
{
printf("Error Opening file.\n");
}
else
{
do
{
note = aserveGetNote();
velocity = aserveGetVelocity();
if (velocity > 0)
{
fprintf(textFilePointer, "%d\n, %d\n", note, velocity);
counter++;
}
program = aserveGetProgram();
} while (counter < 16);
fclose(textFilePointer);
}
}
else if(user == 'x' || user == 'X')
break;
} while(user != 'x' || user != 'X');
return 0;
}
float mtof(int note, float frequency)
{
frequency = 440.0 * pow(2, (note-69) / 12.0);
printf("%d\n", note);
return frequency;
}
int index = 0;
char filename[128];
do
{
printf("Press R to Record (R) or (X) to Exit: \n");
scanf(" %c", &user);
if (user == 'r' || user == 'R')
{
snprintf(filename, 120, "notes%d.txt", (index+1));
textFilePointer = fopen(filename, "w");
counter = 0;
if (textFilePointer == NULL)
{
printf("Error Opening file.\n");
}
else
{
do
{
// your work
} while (counter < 16);
fclose(textFilePointer);
index++;
}
}
else if(user == 'x' || user == 'X')
break;
} while(user != 'x' || user != 'X');
return 0;
int main()
{
FILE *textFilePointer;
char filename[100];
int note;
int velocity;
int program;
int counter = 0;
char user;
float frequency;
int sample = 0;
do
{
printf("Press R to Record (R) or (X) to Exit: \n");
scanf(" %c", &user);
if (user == 'r' || user == 'R')
{
sample++;
sprintf(filename, "/Users/Luke/Desktop/midinotes%d.txt", sample);
textFilePointer = fopen(filename, "w");
counter = 0;
if (textFilePointer == NULL)
printf("Error Opening file.\n");
else
{
do
{
note = aserveGetNote();
velocity = aserveGetVelocity();
if (velocity > 0)
{
fprintf(textFilePointer, "%d\n, %d\n", note, velocity);
counter++;
}
program = aserveGetProgram();
} while (counter < 16);
fclose(textFilePointer);
}
}
else if(user == 'x' || user == 'X')
break;
} while(user != 'x' || user != 'X');
return 0;
}

End a program with the Enter key

I am trying have a program end when the user hits the Enter key. For some reason it doesn't seem to work. When I use "char c is not equal to enter key" it takes in an extra integer in c (the last inputted integer). What is the problem with this code?
#include <stdio.h>
#include <stdlib.h>
#define framenumber 4
int test1 =0;
int test2=1;
int main(void)
{
int mainarray[framenumber][2] = {0}, nHP = 3, takein, iPT;
char c = getchar();
printf("Enter: ");
while(1)
{
char c = getchar();
if(c == '\n') {
printf("here");
}
else
{
printf("not enter\n");
takein = atoi(&c);
for (iPT = 0; mainarray[iPT][test2] != takein && iPT < framenumber; iPT++);
if (mainarray[iPT][test2] != takein)
{
//search for a victim
do {
nHP = (nHP + 1) % framenumber;
} while ( !( mainarray[nHP][test1] == 1 ? mainarray[nHP][test1] = 0 : 1 ) );
//update the page table
mainarray[nHP][test1] = 1;
mainarray[nHP][test2] = takein;
}
else
{
mainarray[iPT][test1] = 1;
}
puts("page table:");
for (iPT = 0; iPT < framenumber; iPT++)
{
printf("%s %d, %d.\n", iPT == (nHP + 1) % 4 ? ">": " ", mainarray[iPT][test1], mainarray[iPT][test2]);
}
putchar('\n');
printf("Enter: ");
}
}
return 0;
}
Do not create block variable. (In while loop).
char c='\0'; /* initialize with 0 */
printf("Enter: ");
while(c!='\n') /* loop terminate condition */
{
c= getchar(); /* remove declaration */
if(c =='\n')
{
printf("here");
}
else
{
getchar(); /* read (eat) an extra input */
printf("not enter\n");
....

Resources