I am looking to have a user enter an 8 digit account number. The code I have seems to work for everything unless you have multiple letters, i.e.: 'bbb' as an input. If that happens, it runs the while loop 3 times, displaying the printf, but not asking for another input.
Any input on how to fix this, or a better way to do it is welcome!
Right now, I'm using:
#include <stdio.h>
int main()
{
int return_val = 0;
int account_number = 0;
int within_range = 0;
printf("Please enter your 8 digit account number:\n");
return_val = scanf("%d", &account_number);
getchar();
getchar();
if((account_number > 9999999) && (account_number < 99999999))
{
within_range = 1;
}
while ((return_val != 1) || (within_range != 1))
{
printf("Invalid account number. Account number must be 8 digits.\n");
printf("Please enter your 8 digit account number: \n");
//scanf("%d", &clear);
return_val = scanf("%d", &account_number);
getchar();
getchar();
if((account_number > 9999999) && (account_number < 99999999))
{
within_range = 1;
}
}
printf("Account #: %d", account_number);
}
Will it help if you read the input as a string of characters (using fgets) and parse it from there using sscanf? You will not have to worry about the extra getchars.
#include <stdio.h>
int get_acct_num()
{
char line[80];
int acct_num;
int return_val = 0;
printf("Please enter your 8 digit account number:\n");
fgets ( line, sizeof ( line ), stdin );
return_val = sscanf(line, "%d", &acct_num);
if ( return_val != 1 )
return ( 0 );
if ( ( acct_num < 10000000 ) || ( acct_num > 99999999 ) )
return ( 0 );
return ( acct_num );
}
int main()
{
int account_number = 0;
while ( ! ( account_number = get_acct_num() ) )
printf("Invalid account number. Account number must be 8 digits.\n");
printf("Account #: %d", account_number);
}
In this case it is better to parse a string
#include <ctype.h>
...
char input[200];
scanf("%s", input);
int len = strlen(input);
int dig = 0;
if (len == 8) {
for ( ; dig<len ; dig++) if ( ! isdigit(input[dig])) break;
}
if (dig == 8) printf("OK\n");
else printf("Not ok\n");
the code ensures we have 8 digits and nothing else in input (prints "OK").
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main()
{
int account_number = 0;
int inval = 0;
char acc_buf[256];
printf("Please enter your 8 digit account number:\n");
scanf("%s", acc_buf);
if (strlen(acc_buf) == 8) {
for (int i = 0; i < 8; i++)
if (!isdigit(acc_buf[i])) {
inval++;
break;
}
} else inval++;
if (!inval) {
account_number = atoi(acc_buf);
printf("Account #: %d\n", account_number);
}
return 0;
}
May I suggest a little rewrite?
#include <stdio.h>
#include <string.h> /* this is for strlen */
#include <stdlib.h> /* this is for atoi */
int main()
{
char input [55]; /* this is to store the user input */
int account_number = 0;
printf("Please enter your 8 digit account number:\n");
while (fgets(input, 55, stdin)[0] == '\n')
; /* this is a safer way to get input, loop until there is input, ignore new lines */
account_number = atoi(input); /* convert to an int */
if (account_number < 10000000 || account_number > 99999999)
return -1;
/* quit if invalid input */
printf("Account #: %d\n", account_number);
return 0;
}
EDIT: I've used fgets here and atoi as I think it would be good to be familiar with those functions. Having said that atoi is not necessarily the best way to convert to an number. Strtol is far more reliable but a little more complicated to use.
This is one way to use strtol in this context:
char* temp = 0;
account_number = strtol(input, &temp, 10); /* convert to an int */
More on the subject of converting strings to numbers here.
EDIT-2:
Taking into account chux's comment, the loop can be constructed like this too:
char* out;
do
{
out = fgets(input, 55, stdin);
}
while (out == NULL || out[0] == '\n')
;
I really don't like using scanf(), prefer fgets(), then sscanf().
Details below.
2 key lines:
if (fgets(buf, sizeof(buf), stdin) == NULL)
...
while (1 != sscanf(buf, " %8lu %c", &AccontNummner, &ch));
Solution
#include <stdio.h>
#include <stdlib.h>
// Get 8 digit account number. Returns -1 on I/O error or EOF
// Parsing error just tries again.
long Get8DigitAccountNumber(void) {
const char *prompt = "Enter 8 digit account number: ";
unsigned long AccontNummner;
char ch; // Extra text
char buf[1024];
do { // or while (1)
ch = '\0';
printf(prompt);
fflush(stdout); // Appears to be needed on some systems.
prompt = "Error, try again: "; // Used on re-try
if (fgets(buf, sizeof(buf), stdin) == NULL) {
return -1; // handle I/O error
}
// If not _exactly_ one 1-8 digit field parsed, then try again.
// Leading and trailing whitespaces are OK
} while (1 != sscanf(buf, " %8lu %c", &AccontNummner, &ch));
return (long) AccontNummner;
}
int main() {
long AccontNummner;
while ((AccontNummner = Get8DigitAccountNumber()) >= 0) {
printf("# %lu\n", AccontNummner);
}
return 0;
}
If you want to read exactly 8 digits ...
int n1 = 0;
int n2 = 0;
} while ((1 != sscanf(buf, " %n%8lu%n %c", &n1, &AccontNummner, &n2, &ch) || ((n2 - n1) != 8));
Acceptable format: [optional whitespaces][1-8 digits][optional whitespaces][nothing more]
sscanf() format: " %8lu %c".
Use %u instead of %d to not allow '-'.
Explicitly allow optional leading and trailing spaces.
The %c catches any non-white char after the 8-digit number.
Scanning anything via %c causes sscanf() to return 2.
It's been a while since I fooled with formatted input in C but try scanf("%8d", &account_number);
Related
I am having an issue with the output of my code, which is trying to return an array backwards in c using pointers. Do you guys have any solutions to the error I am getting?
Sample input:
Please enter the array size: 3
Please enter 3 elements:
4, 5, 7
Segmentation fault (core dumped)
Code:
#include <stdio.h>
int main(void){
int size, i;
int *pointer;
int arr[size];
printf("Please enter the array size: ");
scanf("%d/n", &size);
pointer = &arr[0];
printf("Please enter %d elements: \n", size);
for(i = 0; i < size; i++){
scanf("%d", arr[i]);
pointer++;
}
pointer = &arr[size - 1];
printf("The reversed array is \n");
for(i = size; i > 0; i--){
printf("%d", arr[i]);
pointer--;
}
return 0;
}
The task is not simple for beginners like you and me.
As I have understood the user can enter any number of integers in one line and all entered integers in the line must be outputted like
You entered 2
In this case neither array nor character array nor integer array will help. And in fact you need not to define an array if you want only to output numbers stored in the input buffer.
In this case you can just use the standard function getchar. Using the function in a loop you can read all numbers placed by the user in one line in the I/O buffer.
Here is a sample program. It is a little complicated because I allow the user to enter sign symbols.
There is no check in the program whether the user entered not a digit or a sign. You can develop the program further. The program demonstrates an approach to solve the task.
#include <stdio.h>
#include <ctype.h>
int main( void )
{
const int Base = 10;
printf( "Enter a seria of integer numbers in one line: " );
int c;
int sign = 0;
int num = 0;
do
{
c = getchar();
if (c == EOF || c == '\n' )
{
if (sign)
{
printf( "You entered %d\n", num );
}
}
else if (isblank( ( unsigned char )c ))
{
if (sign)
{
printf( "You entered %d\n", num );
sign = 0;
num = 0;
}
}
else
{
if (c == '-' || c == '+')
{
if (sign)
{
printf( "You entered %d\n", num );
num = 0;
}
sign = c == '-' ? -1 : 1;
}
else if (isdigit( ( unsigned char )c ))
{
c -= '0';
if (sign == 0) sign = 1;
if (sign == 1)
{
num = Base * num + c;
}
else
{
num = Base * num - c;
}
}
}
} while (c != EOF && c != '\n');
}
The program output might look for example like
Enter a seria of integer numbers in one line: 1 -1 +12-12+13 +14 -15
You entered 1
You entered -1
You entered 12
You entered -12
You entered 13
You entered 14
You entered -15
If you want to enter several lines of numbers and output numbers that are present in each line then the program can look the following way
#include <stdio.h>
#include <ctype.h>
int main( void )
{
const int Base = 10;
size_t i = 0;
while (1)
{
printf( "Enter a seria of integer numbers in one line (or press just Enter to exit): " );
int c = getchar();
if (c == EOF || c == '\n') break;
ungetc( c, stdin );
printf( "Line %zu contains the following numbers:\n", i++ );
int sign = 0;
int num = 0;
do
{
c = getchar();
if (c == EOF || c == '\n')
{
if (sign)
{
printf( "You entered %d\n", num );
}
}
else if (isblank( ( unsigned char )c ))
{
if (sign)
{
printf( "You entered %d\n", num );
sign = 0;
num = 0;
}
}
else
{
if (c == '-' || c == '+')
{
if (sign)
{
printf( "You entered %d\n", num );
num = 0;
}
sign = c == '-' ? -1 : 1;
}
else if (isdigit( ( unsigned char )c ))
{
c -= '0';
if (sign == 0) sign = 1;
if (sign == 1)
{
num = Base * num + c;
}
else
{
num = Base * num - c;
}
}
}
} while (c != EOF && c != '\n');
putchar( '\n' );
}
}
The program output might look for example like
Enter a seria of integer numbers in one line (or press just Enter to exit): 1 -2 3 +4
Line 0 contains the following numbers:
You entered 1
You entered -2
You entered 3
You entered 4
Enter a seria of integer numbers in one line (or press just Enter to exit): 11-12 13+14
Line 1 contains the following numbers:
You entered 11
You entered -12
You entered 13
You entered 14
Enter a seria of integer numbers in one line (or press just Enter to exit):
As the program just outputs entered numbers then actually there is no need to build an object of the type int like
num = Base * num + c;
You could just output adjacent digits in a line.
int array[100];
int n;
scanf("%d", &n);
for(int i=0; i<n; i++) {
scanf("%d", &array[i]);
}
for(int i=0; i<n; i++) {
printf("You entered %d \n", array[i]);
}
We use the array to get all of the values, and just print them out at the end.
In C and C++ it does not matter if the values are separated by space or a newline, so you can get every integer in a single line if separated by spaces.
output
3
1 2 3
You entered 1
You entered 2
You entered 3
C makes this very easy, but you need to leverage some library functions. At the most simple:
use fgets() and strpbrk() to obtain and verify a line of text
use strtok() and strtol() to parse and verify integer values.
What you do with those values is up to you. Following your example prompt, let’s just print them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int error( const char * message, const char * value )
{
fprintf( stderr, "%s%s\n", message, value );
return 1;
}
int main()
{
printf( "Input: " );
// Get all input on a single line
char text[1000];
fgets( text, sizeof(text), stdin );
// Verify that the entire line of input was obtained
char * nl = strpbrk( text, "\r\n" );
if (!nl) return error( "Line too long!", "" );
*nl = '\0';
puts( "Output:" );
// For each whitespace-delimited (spaces, tabs) token in the line:
for (char * token = strtok( text, " \t" ); token; token = strtok( NULL, " \t" ))
{
// Attempt to convert it to an integer
char * nok;
int n = strtol( token, &nok, 10 );
if (*nok) return error( "Invalid integer value: ", token );
// Success!
printf( "You entered %d\n", n );
}
return 0;
}
Notice also how it is OK to create a little helper function (error()). You can make helpers as complex or simple as you need. For this helper, all we need was to complain with one or two strings and return an “error happened” exit code that main() can pass right to the shell.
fgets can be used to read a line.
strtol can parse integers and report overflow and invalid input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int parselint ( char *line, int *value, char **end) {
long int number = 0;
errno = 0;
number = strtol ( line, end, 10);
if ( *end == line) {// nothing was parsed. no digits
size_t span = strcspn ( *end, "-+0123456789"); // characters to next int
if ( ! span) {
span = 1;
}
fprintf ( stderr, "problem parsing: %.*s\n", (int)span, line);
*end += span; // advance pointer to next int
return 0;// return failure
}
if ( ( errno == ERANGE && ( number == LONG_MAX || number == LONG_MIN))
|| ( errno != 0 && number == 0)) {// parsing error from strtol
fprintf ( stderr, "problem %.*s", (int)(*end - line), line);
perror ( " ");
return 0;
}
if ( number > INT_MAX || number < INT_MIN) {
fprintf ( stderr, "problem %.*s ", (int)(*end - line), line);
fprintf ( stderr, "out of int range\n");
return 0;
}
*value = number;//assign number to pointer
return 1;//success
}
int main ( void) {
char line[4096] = "";
char *parse = line;
int number = 0;
fgets ( line, sizeof line, stdin);
line[strcspn ( line, "\r\n")] = 0; // remove newline
while ( *parse) {
if ( 1 == parselint ( parse, &number, &parse)) {
printf ( "you entered %d\n", number);
}
}
return 0;
}
Actually, I can easily found a similar question in Google, but it still can not solve my question.
How to prevent non-numeric input in C?
The upper-link is like a similar case.
Here is my code
#include <stdio.h>
int main()
{
int n;
printf("Enter 1 or 2?\n");
scanf("%d", &n);
while(n != 1 && n != 2)
{
printf("Please do not enter other characters\n");
printf("Enter 1 or 2?\n");
scanf("%d", &n);
}
}
I hope if users enter other numbers(e.g. 1, 45, 656), characters (e.g. a, f, u, e), or string(e.g. apple), the upper program can print out an error message and ask for user input again.
Yes! if users enter other numbers, the program can do what I want.
But! if users enter other characters, string, the program will keep looping.
What should I need to add to this program?
How to prevent non-numeric input in C & ask user input again
Do not use scanf()**. Use fgets().
scanf("%d", ...) does not consume non-numeric input. Instead that offending input remains in stdio for the next scanf().
Code cannot prevent non-numeric input unless it locks the keys from being pressed. Instead, read all input, identify the non-numeric text, toss it and present the user with feedback for new input.
Make a helper function to control impact on rest of code.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
// return -1 on EOF
int read_int_in_range(const char *prompt, const char *reprompt, int lo, int hi) {
if (prompt) {
fputs(prompt, stdout);
fflush(stdout);
}
char buf[100];
while (fgets(buf, sizeof buf, stdin)) {
char *endptr;
errno = 0;
long val = strtol(buf, &endptr, 10);
// no overflow, conversion occurred, in range
if (errno == 0 && endptr > buf && val >= lo && val <= hi) {
// Tolerate trailing white-space.
while (isspace((unsigned char ) *endptr)) {
endptr++;
}
// No junk after the numeric text
if (*endptr == '\0') {
return (int) val;
}
}
if (reprompt) {
fputs(reprompt, stdout);
fflush(stdout);
}
}
return EOF; // or `INT_MIN` or TBD code to distinguish `int` from an error.
}
Usage
const char *prompt = "Enter 1 or 2?\n";
const char *reprompt = "Please do not enter other characters\n" "Enter 1 or 2?\n";
int n = read_int_in_range(prompt, reprompt, 1, 2);
**I recommend to not use scanf() anywhere to read user input until ones understands its weaknesses and limitations.
scanf is meant for formatted input, ie: you know what input will be received, in this case the user may enter something other than an int and your program breaks down. So to deal with that unknown treat the input as a string then analyze the string. In this case you could capture the input in buf and use the function atoi to convert it to an int, like this:
#include <stdio.h>
#include <stdlib.h> /* for atoi */
int main()
{
int n;
char buf[10]; /* this is new */
printf("Enter 1 or 2\n");
/*scanf("%d", &n);*/
fgets(buf, 10, stdin);
n = atoi(buf);
while(n != 1 && n != 2)
{
printf("Please do not enter other characters\n");
printf("Enter 1 or 2?\n");
/*scanf("%d", &n);*/
fgets(buf, 10, stdin);
n = atoi(buf);
}
}
fgets is the way to do this, but wanted to post something like this to actually avoid fgets as asked. It may be of some interest. The appending part should've been delegated to some function and buffer size may've not been 10. Anyways:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define endl "\n"
int main (void)
{
int my_char = 0;
short bad = 0;
char text[10];
memset (text, 0, 10);
printf ("enter number: ");
while ( (my_char = getchar()) )
{
if ( my_char < '0' || my_char > '9' )
{
if ( my_char != '\n' ) bad = 1;
}
else
{
size_t len = strlen (text);
char *strtemp = malloc (len + 2);
strcpy (strtemp, text);
strtemp [len] = my_char;
strtemp [len + 1] = '\0';
strncpy (text, strtemp, 9);
free (strtemp);
}
if ( my_char == '\n' )
{
if ( bad )
{
printf ("enter again (just numbers): ");
fflush (stdout);
bad = 0;
memset (text, 0, 9);
}
else break;
}
}
printf ("entered: %s"endl, text);
}
How can I assign a integer and float values given by user to a variable or array without using scanf()?
Like we have getchar,fgetc,fgets...etc for char and string, Is there any function for floats and integers ?
There aren't functions to read integers and floats but you can use fgets with strtol for integers and strtof for floats:
// floats:
char str_f[20];
float f;
fgets (str_f, 20, stdin);
f = strtof(str_f, NULL);
// integers:
char str_i[20];
int i;
fgets(str_i, 20, stdin);
i = strtol(str_i, NULL, 0);
You can also use atoi for integers but it's not recommended because atoi doesn't detect errors and it's considered obsolete.
If you want to detect errors you can use the following code:
// floats:
char *endptr_f;
char str_f[20];
float f;
fgets (str_f, 20, stdin);
f = strtof(str_f, &endptr_f);
if (*endptr_f != '\n' || str_f[0] == '\n' || endptr_f == str_f)
{
printf("ERROR: \"%s\" is an invalid float!\n", str_f);
}
// integers:
char *endptr_i;
char str_i[20];
int i;
fgets(str_i, 20, stdin);
i = strtol(str_i, &endptr_i, 0);
if (*endptr_i != '\n' || str_i[0] == '\n' || endptr_i == str_i)
{
printf("ERROR: \"%s\" is an invalid integer!\n", str_i);
}
Years ago I wrote this, Tested in VS2017 and still works. Very simple, Not very good but maybe you can use it for something
#define INT_CONVERTED (1 << 0)
#define FLOAT_CONVERTED (1 << 1)
char *strlwr(char *str)
{
char *ptr = str;
while (*ptr)
{
*ptr = tolower(*ptr);
ptr++;
}
return str;
}
int NumberOfDots(char *s)
{
int dots = 0;
while (*s)
dots += *s++ == '.';
return dots;
}
int NOTstrcasechr(char *str, int ch)
{
return strchr(str, ch) == NULL && strchr(str, toupper(ch)) == NULL;
}
int ReadNumber(double *db, int *in)
{
int result = 0;
do
{
char str[100];
int dots;
result = 0;
printf("Enter number: ");
fgets(str, 100, stdin);
if ((dots = NumberOfDots(str)) > 1) str[0] = '\0';
if (sscanf(str, "%lf", db) == 1)
{
result |= FLOAT_CONVERTED;
}
if (!result || (!dots && NOTstrcasechr(str, 'e')))
if (NOTstrcasechr(str, 'x'))
{
if (sscanf(str, "%d", in) == 1)
{
result |= INT_CONVERTED;
}
}
else
if(result)
{
result |= INT_CONVERTED;
*in = (int)*db;
}
if (strstr(strlwr(str), "exit") != NULL) result = -1;
} while (!result);
return result;
}
int main(int argc, char **argv)
{
double db;
int in;
int result;
while ((result = ReadNumber(&db, &in)) != -1)
{
if (result & FLOAT_CONVERTED) printf("Float = %lf ", db);
if (result & INT_CONVERTED) printf("Integer = %d ", in);
printf("\n\r");
}
return 0;
}
Enter number: xfdsfdsfdsf
Enter number: rthdgfhghg
Enter number: 0x4567
Float = 17767.000000 Integer = 17767
Enter number: 3e67
Float = 30000000000000000978680950144401383192292617328216608963406365458432.000000
Enter number: 54567
Float = 54567.000000 Integer = 54567
Enter number: dfgdfgdfgdfgdgg
Enter number: 3456
Float = 3456.000000 Integer = 3456
Enter number: 12354654465454654654565567567576
Float = 12354654465454653961713368432640.000000 Integer = -1
Enter number: exit
Is there any function for floats and integers ?
Yes, it is scanf(), yet OP does not want to use that.
How to get Integer and float input without scanf()?
This is not a trivial task to do just like scanf("%d", &some_int), scanf("%f", &some_float).
The primary problem is to stop reading characters once the longest valid input is consumed - this could be in the middle of a line of user input. I did not find a terse robust solution.
Instead, talcked the problem of reading a line of user input for one integer long. Reading a float is similar. Changes needed near *** lines
Still the problem of finite text length occurs. The below code assumes valid input is made of up to 2x the maximum needed to print a long.
Overflow is an issue somewhat addressed here. Recall with scanf(), OF/UF is undefined behavior.
The central idea is to read a line by skipping whitespace, reading N characters and then looking for any non-white space after that. Then parse the buffer.
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// character array size needed to represent all `long`
#define INT_STR_SIZE (sizeof(long)*CHAR_BIT/3 + 3)
#define INT_BUF_SIZE (INT_STR_SIZE*2)
int readline_long(long *dest) { // ***
int ch;
while (isspace(ch = getchar()) && ch != '\n') {
;
}
if (ch == EOF) return EOF;
ungetc(ch, stdin);
char buf[INT_BUF_SIZE]; // ***
if (fgets(buf, sizeof buf, stdin) == NULL) return EOF;
if (strchr(buf, '\n') == NULL) {
// Get rest of line
bool only_white_space = true;
while ((ch = getchar()) != '\n' && ch != EOF) {
if (!isspace(ch)) only_white_space = false; // consume rest of line
}
if (!only_white_space) return 0; // extra junk
}
char *endptr;
errno = 0;
long y = strtol(buf, &endptr, 10); // ***
if (buf == endptr) return false; // no conversion
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (*endptr) return 0; // extra junk
*dest = y;
return 1;
}
Test code
int main(void) {
long lg;
int retval;
while ((retval = readline_long(&lg)) != EOF) {
printf("retval = %d", retval);
if (retval > 0) printf(" val = %ld", lg);
if (errno) printf(" errno = %d", errno);
putchar('\n');
fflush(stdout);
}
}
That's my code so far:
int main(void) {
int byte[8], position = 0, match8 = 0;
printf("Please enter 1 byte as a binary sequence: ");
match8 = scanf("%1d%1d%1d%1d%1d%1d%1d%1d", &byte[0], &byte[1], &byte[2], &byte[3], &byte[4], &byte[5], &byte[6],&byte[7]);
return 0;
}
Now I want to make sure that the user made a correct input and if not the program should say "Error! Please enter 1 byte as a binary sequence: " and check the input again.
I tried:
while(getchar() != '\n' || match8 != 8) {
...do something
}
But I can't figure out how to check if the array contains only 0 and 1.
I hope you can help me with my problem :)
try this
char bits[9], ch;
int byte[8];
while(1){
printf("Please enter 1 byte as a binary sequence: ");fflush(stdout);
bits[8] = 1, ch = 0;
if(2 == scanf(" %8[01]%c", bits, &ch) && ch == '\n' && bits[8] == 0)
break;
if(ch != '\n')
while(getchar() != '\n');//clear input
printf("Error! ");
}
sscanf(bits, "%1d%1d%1d%1d%1d%1d%1d%1d", &byte[0], &byte[1], &byte[2], &byte[3], &byte[4], &byte[5], &byte[6],&byte[7]);
A scanset %8[01] could be used to restrict input to the characters 0 and 1. The 8 will also limit input to 8 characters. The characters can be converted to numbers with number = onezero[i] - '0';
#include <stdio.h>
#include <string.h>
int main( void) {
char onezero[9] = "";
int valid = 0;
do {
printf("Please enter 1 byte as a binary sequence: ");
if ( ( 1 == ( valid = scanf ( " %8[01]", onezero))) && ( 8 == strlen ( onezero))) {
printf ( "input was %s\n", onezero);
}
else {
if ( valid == EOF) {
break;
}
while ( getchar ( ) != '\n') {}
valid = 0;
}
} while ( !valid);
return 0;
}
Suggest to avoid scanf() and use fgets() to read a line of user input
char buf[100];
if (fgets(buf, sizeof buf, stdin)) {
Then use strspn() to test buf[] for only '0' or '1'
size_t strspn(const char *s1, const char *s2);
The strspn function computes the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters from the string pointed to by s2. C11 7.23.5.6
size_t offset = strspn(buf, "01");
if (buf[offset] == '\n') {
buf[offset--] = '\0'; // eat trailing \n
}
if (offset == 8 && buf[offset] == '\0') {
sscanf(buf, "%1d%1d%1d%1d%1d%1d%1d%1d",
&byte[0], &byte[1], &byte[2], &byte[3], &byte[4], &byte[5], &byte[6],&byte[7]);
// Success!
}
}
try this...
int main(void) {
int byte[8]={0};
printf("Please enter 1 byte as a binary sequence: ");
for(int i=0; i<8; i++)
{
byte[i]=getchar()-'0';
if(byte[i]!=0&&byte[i]!=1) /*error*/;
}
return 0;
}
everyone!
I hope someone can help me figure out something in C language.
This is my first seriously homework in IT, I have no experience and I'm learning in e-studies, so teacher help isn't very available.
I need to develop console application in C language. User need to input 10 integer numbers, if insert number isn't integer, need to output error and again re-enter new number until all 10 integer numbers will be inserted.
Everything works in case if I say that these 10 numbers can't be 0 (I make this to be sure that my if-else statement working), but won't work when I want that every input number will be check if it is integer or not.
How can I do it right.
Please help
so far my code look like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
float f;
int numbers[10];
for (i = 0; i < 10; i++)
{
scanf ("%d", &numbers[i]);
if (numbers[i] != 0)
{
scanf ("*%d", &numbers[i]);
}
else
{
printf ("\nError!Entered number is't integer \n");
printf ("\nPlease insert number again \n");
scanf("%*d", &numbers[i]);
}
}
}
#include <stdio.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
val = scanf("%d", numbers + i); // read the integer into a[i]
if(val != 1) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
val = scanf("%d", numbers + i);
continue;
}
++i;
}
// process the numbers array
return 0;
}
I write this line again
val = scanf("%d", numbers + i);
Now it works how I need. Great - thanks a lot
There are several techniques you might use:
Read the number as a string and reject if it contains characters not suitable for an integer. The use sscanf() to convert the string to integer.
Read the number as a float and reject if it is out of integer range or it has a non-integer value.
Read the input character by character and build up an integer value. If invalid characters appear, reject the value.
scanf returns the number of input items successfully matched and assigned. You can check this value for 1 for each call of scanf. If the value is 0, then you should discard the input to clear the stdin buffer and read input again.
#include <stdio.h>
#include <ctype.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
// read an integer and the first non-numeric character
val = scanf("%d%c", numbers + i, &ch);
// if the number of items assigned by scanf is not 2 or if
// the first non-numeric character is not a whitespace, then
// discard the input and call read input again.
// for example input of type 32ws are completely discarded
if(val != 2 || !isspace(ch)) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
++i;
}
// process the numbers array
return 0;
}
Although I am not entirely clear on the details of your question, here is an outline of code similar to what you want:
int main(void)
{
int i;
int numbers[10];
int sum = 0;
for(i=0; i<10; ++i)
{
printf("Enter #%d:\n", i+1);
scanf("%d", numbers+i);
if (numbers[i] % 2 == 0) // Then Number is even
{
sum += numbers[i];
}
}
printf("The sum of only the even numbers is %d\n", sum);
getch();
return 0;
}
To read an int, suggest fgets() then sscanf() or strtol()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int numbers[10];
for (i = 0; i < 10; ) {
char buffer[50];
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
int n; // number of `char` parsed
if (sscanf(buffer, "%d %n", &numbers[i], &n) != 1 || buffer[n] != '\0') {
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
i++;
}
return 0;
}
The strtol() approach. This detects overflow issues:
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
char *endptr;
errno = 0;
long num = strtol(buffer, &endptr, 10);
if (errno || num < INT_MIN || num > INT_MAX) Handle_RangeError();
if (buffer == endptr || *endptr != '\n') Handle_SyntaxError();
numbers[i] = (int) num;
Recommend making a int GetInt(const char *prompt) function that can be used repeatedly.
User input is evil. Do not trust it until well vetted.