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);
}
}
Related
I have a file which stores values like 2.32x7.
I read the floating-point part using:
fscanf(file, "%lf", &value);
It works perfectly... except for when the file stores something like 0x2. In that case, it reads the entire string as a hexadecimal value.
How can I prevent this from happening?
I would like fscanf to just read 0 and ignore x2.
Edit:
As suggested by #dbush, I am adding a sample input file.
I am parsing polynomials. So, the input file will be something like:
0x2+2.32x7-4x-9
Runnable example.
For your purpose, you should read the full polynomial with fgets() and parse it with as hoc code using strtod() and strtol():
#include <errno.h>
#include <stdlib.h>
int parse_polynomial(struct polynomial *p, const char *s) {
for (;;) {
double factor = 1;
int exponent = 0;
char *p;
while (isspace((unsigned char)*s) {
s++;
}
if (*s == '\0')
break;
if (*s == '+') {
s++;
} else
if (*s == '-') {
factor = -1;
}
if (*s != 'x') {
errno = 0;
factor *= strtod(s, &p);
if (p == s || errno != 0) {
/* parse error */
break;
}
s = p;
}
if (*s == 'x') {
exponent = 1;
s += 1;
if (isdigit((unsigned char)*s) {
unsigned long ul;
errno = 0;
ul = strtoul(s, &p, 10);
if (p == s || errno != 0 || ul > INT_MAX)
break;
exponent = (int)ul;
s = p;
}
}
add_component(p, factor, exponent);
}
return (*s == '\0') ? 0 : -1;
}
Reading the line with fgets() and then parsing with crafted code is the most robust.
To read text as a single floating point number with fscanf() up to an 'x', first read with a scanset and then convert.
char buf[400 + 1]; // Something large - consider DBL_MAX may be 1e308
// Scanset of expected FP characters
#define FP_FMT " %400[-+.eE0-9]"
// or maybe simply
#define FP_FMT " %400[^x]"
if (fscanf(FP_FMT, buf) == 1 && sscanf(buf, "%lf", &value) == 1) {
// Success
Pedantic code would use strtod() instead of sscanf(buf, "%lf", &value).
Other consideration include locale use of ',' as the decimal point, NAN, infinity, even wider text as wee exact FP values, how to handle ill formatted text, input errors, EOF, ...
Consider scanning the pair of value and exponent in 1 step.
if (fscanf(FP_FMT "x%d, buf, &power) == 2 && sscanf(buf, "%lf", &value) == 1) {
❗❗❗ Incorrectly handles numbers with dots...
Thinking, how to fix that.
You can read the numeric characters, then parse number from the string: example
#include <stdio.h>
int main()
{
double value;
char s[32];
*s = 0;
scanf("%31[0-9]", s);
sscanf(s, "%lf", &value);
printf("%f\n", value);
scanf("%3s", s);
puts(s);
}
If you need negative numbers too: example
#include <stdio.h>
int main()
{
double value;
char s[32];
*s = 0;
scanf("%1[-+]", s);
scanf("%30[0-9]", s+!!*s);
sscanf(s, "%lf", &value);
printf("%f\n", value);
scanf("%3s", s);
puts(s);
}
Note that the last code eats the sign even if it's not followed by digits.
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;
}
I would appreciate some help with this. I'm trying to create this simple program that repeatedly loops asking for the user to enter in an int. If he enters an int, it exits but if he enters something else or bigger than int (ex.4gs4r33) it will loop again asking to enter an int. This is what I have tried, and it's not working. It says it's an int even if it's not.
#include<stdio.h>
unsigned int findInt();
int main() {
printf("Please input an int.\n");
findInt();
}
unsigned int findInt() {
char input;
long num = 0;
int b = 0;
do {
scanf("%c", &input);
if (isdigit(input)){
num = num*10+input+'0';
b = 1;
}
else if (input == '\n')
b = 1;
else
b = 0;
} while(input != '\n');
if (b == 1)
printf("Great!\n");
else{
printf("Not an int \n");
findInt();
}
return 0;
}
Two possible approaches. One would be to modify your code:
b = 1; // start off with good intentions…
do {
scanf("%c", &input);
if (isdigit(input)){
num = num*10+input -'0'; // *** SUBTRACT '0', don't add it!
}
else if (input != '\n') {
b = 0;
break; // *** break when you find non-digit
}
} while (input != '\n');
Two changes: getting the math right as you compute the integer, and fixing the logic (so you break out of your loop when you find a non digit character)
Second approach:
char buf[100];
char intAsString[100];
fgets(buf, 100, stdin);
sscanf(buf, "%d", num);
sprintf(intAsString, "%d\n", num);;
if(strcmp(buf, intAsString) == 0 ) {
printf("yay - you entered an integer!\n");
}
I'm sure you can figure out how that works.
update a complete code snippet that solves the issue of "loop logic" as well: you call the findInt function once from the top level, and it keeps going until you get the int. Note - in order for this to work properly, I read the entire input at once (rather than one at a time), then pick off the characters one by one using sscanf (and updating the pointer manually). It has a number of advantages - not least of which is that you start with a fresh input every time you call findInt, instead of having the rest of the input buffer that still needs reading (and which was giving rise to "no,no,no,great!" - as you would keep reading the bad input until you got to the newline, and accept that...)
#include<stdio.h>
#include <ctype.h>
unsigned int findInt();
int main() {
findInt();
}
unsigned int findInt() {
char input;
char buf[100];
char *temp;
long num = 0;
int b = 0;
printf("please enter an int:\n");
fgets(buf, 100, stdin);
temp = buf;
do {
sscanf(temp++, "%c", &input);
if (isdigit(input)){
num = num*10+input-'0';
b = 1;
}
else if (input == '\n')
{
b = 1;
break;
}
else {
b = 0;
break;
}
} while(input != '\n');
if (b == 1)
printf("Great! %d is an integer!\n", num);
else{
printf("Not an int \n");
findInt();
}
return 0;
}
In the else branch - i.e. not a digit or a newline - you set b to 0. Now if a digit DOES follow you reset that to 1.
You'll probably want to break or somehow record the permanent failure instead of just continuing.
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
void findInt(){
int x;
bool ok;
do{
char buff[32], *endp;
long long num;
ok = true;//start true(OK)
printf("Enter a number: ");
fgets(buff, sizeof(buff), stdin);
//strtoll : C99
x=(int)(num=strtoll(buff, &endp, 0));//0: number literal of C. 10 : decimal number.
if(*endp != '\n'){
if(*endp == '\0'){
printf("Too large!\n");//buffer over
while('\n'!=getchar());
} else {
printf("Character that can't be interpreted as a number has been entered.\n");
printf("%s", buff);
printf("%*s^\n", (int)(endp - buff), "");
}
ok = false;
} else if(num > INT_MAX){
printf("Too large!\n");
ok = false;
} else if(num < INT_MIN){
printf("Too small!\n");
ok = false;
}
}while(!ok);
}
,
Consider the following simple C program.
//C test
#include<stdio.h>
int main()
{
int a, b, c;
printf("Enter two numbers to add\n");
scanf("%d%d",&a,&b);
c = a + b;
printf("Sum of entered numbers = %d\n",c);
return 0;
}
How do you check the values entered are actually two integers in some sensible range? Currently, if you just enter "a" and then return you get the output "Sum of entered numbers = 32767".
Examples of incorrect input I would like to prevent.
2 3 4 (wrong number of numbers)
apple (not a number)
11111111111111111111111111 1111111111111111111111111111111111111 (numbers out of range)
Or should I be using fgets and sscanf or even strtol ?
User input is evil. Parse per:
(optional whitespace)[decimal int][whitespace][decimal int](optional whitespace)
strtol() and family have better error handling than scanf().
Coda: Best to handle user input in a helper function. Break into 2 parts: I/O and parsing.
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
// return 1 (success), -1 (EOF/IOError) or 0 (conversion failure)
int Readint(const char *prompt, int *dest, size_t n) {
char buf[n * 21 * 2]; // big enough for `n` 64-bit int and then 2x
fputs(prompt, stdout); // do not use printf here to avoid UB
fflush(stdout); // per #OP suggestion
if (fgets(buf, sizeof buf, stdin) == NULL) {
return -1;
}
const char *p = buf;
while (n-- > 0) {
char *endptr;
errno = 0;
long l = strtol(p, &endptr, 10);
if (errno || (p == endptr) || (l < INT_MIN) || (l > INT_MAX)) {
return 0;
}
*dest++ = (int) l;
p = endptr;
}
// Trailing whitespace OK
while (isspace((unsigned char) *p)) p++;
// Still more text
if (*p) return 0;
return 1;
}
int main() { // for testing
int Result;
do {
int dest[2] = { -1 };
Result = Readint("Enter two numbers to add\n", dest, 2);
printf("%d %d %d\n", Result, dest[0], dest[1]);
} while (Result >= 0);
return 0;
}
You can use like:
if( scanf("%d%d",&a,&b) == 2)
{
//two integer values has been read successfully
//do your stuff here
}
else
{
//Wrong input
}
Also you can do this to prevent anything after second number
int a,b;
char c;
if( scanf("%d%d%c", &a, &b, &c) == 3) {
if (c == '\n') {
puts("good");
}
} else {
puts("bad");
}
return 0;
}
You can use the following macro
#define SCAN_ONEENTRY_WITHCHECK(FORM,X,COND) \
do {\
char tmp;\
while(((scanf(" "FORM"%c",X,&tmp)!=2 || !isspace(tmp)) && !scanf("%*[^\n]"))\
|| !(COND)) {\
printf("Invalid input, please enter again: ");\
}\
} while(0)
and you call it in this way in the main
int main()
{
int a, b, c;
printf("Input first integer, valid choice between 0 and 10: ");
SCAN_ONEENTRY_WITHCHECK("%d",&a,(a>=0 && a<=10));
printf("Input second integer, valid choice between 0 and 10: ");
SCAN_ONEENTRY_WITHCHECK("%d",&b,(b>=0 && b<=10));
c = a + b;
printf("Sum of entered numbers = %d\n",c);
return 0;
}
for more detail concerning this macro please refer to: Common macro to read input data and check its validity
A simple way would be,
int a=0, b=0, c=0;
initialise them to 0
Additionally, the check suggested by Midhun is good to check if there are two inputs.
you can test this one.
#include <stdio.h>
int main(void)
{
int a, b, c;
printf("Enter two numbers to add\n");
scanf("%d%d",&a,&b);
if(scanf("%d%d",&a,&b) == 2)
{
c = a + b;
printf("Sum of entered numbers = %d\n",c);
}
return 0;
}
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);