New to C, using user input in multiple functions - c

I'm trying to create multiple functions using the same user input, I'm starting with decimal so I have an input function and the output
Next I'm going to do hexadecimal/ 8 bit binary and so on but I think I have the syntax wrong. I'm confused, I thought that you called the user input from main but I don't think that's correct.
Is there any advice anyone has that can help ? It says the variables are conflicting
#include <stdio.h>
int main (void)
{
int x;
scanf("%d", &x);
in_decimal();
out_decimal(x);
}
int in_decimal(void) {
printf(" Please type in a decimal:");
}
void out_decimal(int x;){
printf("%d",&x);
}

Try this uncompleted code:
#include <stdio.h>
#include <ctype.h>
unsigned int in_decimal();
void out_decimal(unsigned int x);
int main (void)
{
unsigned int x;
x = in_decimal();
out_decimal(x);
}
unsigned int in_decimal()
{
printf("Please type in a decimal: ");
int ch;
unsigned int x = 0;
do
{
ch = getchar();
if( ch < '0' || ch > '1')
{
break;
}
else
{
x *= 2;
x += ch - '0';
}
}
while( ch != '\n');
return x;
}
void out_decimal(unsigned int x){
if(x > 0)
{
out_decimal(x/2);
}
putchar('0' + x%2);
}
Now out_decimal() is recursive function and always output 0 at the beginning of numbers that are greater than zero. Think what you can change :-)

Related

How to incorporate an input array in this program

This is a code that has to take an input array from the user and input the same after removing the duplicates. However, I am unsure on how to incorporate an input array in this, and right now it has the elements hardcoded. This is my first week of programming so I apologize if this is a silly question. This is the code:
#include <stdio.h>
#include <stdbool.h>
#define nelems 8
int main()
{
int l[nelems] = {1,2,3,1,4,4,5,6};
for(int m=0;m<nelems;m++)
{
bool wase = 0;
for(int n=0;n<nelems && m>n;n++)
{
if (l[m] == l[n] && m != n)
wase = 1;
}
if (wase == 0){
printf("%d\n", l[m]);
}
}
return 0;
}
Try using a for loop and scanf.
int i;
for(i=0;i<nelems;i++){
scanf("%d",&l[i]);
}
This is what you need.
#include <stdio.h>
#include <stdbool.h>
#define nelems 8
int main()
{
int i;
int l[nelems] ;
for(i=0;i<nelems;i++)
{
printf("enter %d number :",i);
scanf("%d",&l[i]);
}
for(int m=0;m<nelems;m++)
{
bool wase = 0;
for(int n=0;n<nelems && m>n;n++)
{
if (l[m] == l[n] && m != n)
wase = 1;
}
if (wase == 0){
printf("%d\n", l[m]);
}
}
return 0;
}
If you like int-type array, you can just declare another one:
int input[nelems];
and follow the user968000 advice, remembering that when you are typing the sequence in your console you have to put a white space between each number.
To avoid that, I'd rather use char-type arrays, declared as follows:
char l[nelems] = {'1', '2', '3' /*etc.*/};
char input[nelems];
Then you make a for loop, as user968000 suggested:
int i;
for(i=0;i<nelems;i++)
scanf("%c", &input[i]);
In this case you won't need the white spaces between the digits. Notice the '&' character in the scanf function: just put it as I showed, you'll surely learn what it is in next lessons.
So you have an input array and you can handle it as you want.

Decimal to Binary Program

I am working on an assignment for a C Programming course in regards to converting a decimal to binary using a function that takes in an unsigned char as its input and has a void output. The function will print the binary code of the unsigned char. A hint for the assignment is to create an array of exponents starting with 128 and going down to 1.
I started working on the assignment and ran the debugger, but my program is not working and I am getting a run time error message: Run-Time Check Failure #2 - Stack around the variable userInput was corrupted.
I would appreciate some suggestions on how I can fix my code and if there is a much simple way to write it in order to make the code easier to understand.
#include <stdio.h>
#include <stdlib.h>
unsigned char DecimalToBinary(unsigned char decimalInput);
void main() {
unsigned char userInput = ' ';
unsigned char resultOfUserInput = DecimalToBinary(userInput);
printf("Enter a number less than 256: ");
scanf_s("%u", &userInput);
printf("%u in binary: %u", userInput, resultOfUserInput);
system("pause");
}
unsigned char DecimalToBinary(unsigned char decimalNumber) {
int arrayOfExponents[128] = {}, i = 1, j;
while (decimalNumber > 0) {
arrayOfExponents[i] = decimalNumber % 2;
i++;
decimalNumber = decimalNumber / 2;
}
for (j = i - 1; j > 0; j--) {
printf("%i", arrayOfExponents[j]);
}
return 0;
}
%u reads an unsigned int (say 4 bytes) and you are trying to read it into variable userInput (1 byte)
Few things
1) scanf_s("%u", &userInput); please change it to scanf_s("%c", &userInput);
2) You are calling DecimalToBinary before reading user input
#include <stdio.h>
#include <stdlib.h>
unsigned DecimalToBinary(unsigned char decimalInput);
int main(void) {//void is invalid as a return value.
unsigned userInput = 256;
unsigned resultOfUserInput;//DecimalToBinary(userInput);userInput did not input at this point.
printf("Enter a number less than 256: ");
if(1 != scanf_s("%u", &userInput)){
printf("invaid input!\n");
return EXIT_FAILURE;
}
if(userInput >= 256){
printf("More than 256 of the value has been entered.\n");
return EXIT_FAILURE;
}
resultOfUserInput = DecimalToBinary((unsigned char)userInput);
printf("%u in binary: %u\n", userInput, resultOfUserInput);
system("pause");
return 0;
}
unsigned DecimalToBinary(unsigned char decimalNumber) {
unsigned bin = 0, exp = 1;//assert(sizeof(unsigned) >= 4);
while (decimalNumber > 0) {
bin += (decimalNumber & 1) * exp;
decimalNumber >>= 1;
exp *= 10;
}
return bin;
}
This is an easy way to convert numbers from base 10 to any other base using recursion. I have shared one example with you. You can have any other number as your base.
#include <stdio.h>
void baseconvert(int number,int base)
{
if(number > 0)
{
int digit = (number % base);
baseconvert(number / base, base);
printf("%d",digit);
}
else
{
printf("\n");
}
}
int main()
{
baseconvert(1023,2);
return 0;
}

Diffrence Between The Following Codes

The Following two Codes Yield the same output but has some diffrence which i couldn't figure out
1.
#include<stdio.h>
int main(void)
{
int a=1;
while(a>0)
{
scanf("%d",&a);
if(a != 42)
printf("%d\n",a);
else
break;
}
}
2
#include <stdio.h>
int main(void) {
int x;
for(; scanf("%d",&x) > 0 && x != 42; printf("%d\n", x));
return 0;
}
The working is different because the semantics are different because the code is different.
If you would want to rewrite the 2nd part to the 1st, you would get
#include <stdio.h>
int main(void) {
int x;
while (scanf("%d",&x) > 0 && x != 42) {
printf("%d\n", x);
}
return 0;
}
or
int main(void) {
int a;
while (scanf("%d",&a) > 0) {
if (x != 42) {
printf("%d\n", x);
} else {
break;
}
}
return 0;
}
Do you see the difference? On the one, you base your decision on the variable being scanned (x or a) and on the other on the return value of scanf(), which is simply the number of values read:
while(a>0)
vs.
while (scanf("%d",&a) > 0)
In the first case it's simple looping structure.
In the second case. The For Loop arguements like initialization of looping variable, condition and incrementation/decremenation are always options.
here For loop initialization is omitted, the condition scanf("%d",&x) will return no of values properly read from console, in case if you give any random character as input scanf return 0 and the condition x!= 42 is obvious. printf in the incremation/decrematation place just prints.
Only when the condition fails the loop terminates.

How to test input is sane

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;
}

C: How can I read unkown number of integers inside parenthesis from input?

It's quite bothering when reading unknown number of integers within a pair of parenthesis.
For example:
(1, 2, 3)
But We don't how many integers there are.
Rather than reading them entirely as a string, can anyone have any other ideas to fix that?
Many thanks.
It is terribly unclear what you really want from the posted question. But if you're talking about variable length arguments to a function, then:
Look into Variable arguments in C.
If you are talking about reading unknown no. of integers from input buffer, then you'll have to make your own function to read character by character, parsing the input for numbers, parenthesis and commas: A basic parser to do that is below(note, its not tested and can contain bugs) - understand and modify it accordingly. You can read in any no. of integers with this program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef enum { START, OPAREN, CPAREN, COMMA, DIGIT, EOF_S,UNKNOWN }Token;
int c;
unsigned char state = 0;
int numbers[100];
Token getToken(FILE *f)
{
while(isspace(c = fgetc(f)));
if(c == EOF) return EOF_S;
if(c == '(') return OPAREN;
if(c == ',') return COMMA;
if(c == ')') return CPAREN;
if(isdigit(c)) return DIGIT;
return UNKNOWN;
}
int getNumber(FILE *f)
{
int returnNumber = 0;
Token tok = START;
while(tok != DIGIT){
tok = getToken(f);
if(tok == UNKNOWN){ state = 1; return 0x0FFFFFFF;}
if(tok == EOF_S) { state = 2; return 0x0FFFFFFF;}
}
if(tok == DIGIT){
while(tok == DIGIT){
returnNumber = returnNumber * 10 + (c - '0');
tok =getToken(f);
}
}
return returnNumber;
}
int getNumbers(FILE *f, int *numbers_0)
{
int number;
int no_counter = 0;
while(((number = getNumber(f)) != 0x0FFFFFFF) && (state == 0)){
numbers_0[no_counter++] = number;
}
return no_counter; //returns no. of numbers between ( and ), separated by ','
}
int main(int argc, char *argv[])
{
int no, i;
no = getNumbers(stdin,numbers);
if(no > 100) no = 100;
for(i = 0; i < no; i++){
printf("%d\n",numbers[i]);
}
return 0;
}
Here after a simple C code to do it
#include <stdio.h>
int main(int argc, char **argv)
{
int x; char c='\0';
scanf("%*[(]");
while (c != ')' && scanf("%d %c", &x, &c)==2){
if (c!=',' && c != ')') {
printf ("format error in the input\n");
break;
}
printf("Number: %d\n", x);
}
}
If your input stream is stdin then use scanf as indicated in the above code
If your input stream is a file then use fscanf
if u need only read ( and processing right now) u can
read char C until C=='('
read char C if it space/tab/CR/LF continue step 2 else step 3
if C==')' End of reading list
so if u here c is a digit so u can getback char( use ungetc(C,stdin) ) and reread all number as integer .here u can opirate with intger as u wish. continue to 2.
If list is syntax correct above algo enogh else add where read C test on EOF and on step 4 test on alpha.
I think u can rewrite algo using C without goto.
I hope you are looking for a function implementation with variable arguments, below snippet will help you.
int add(int *total, int count, ...)
{
int i = 0;
va_list numbers;
va_start(numbers, count);
for (i = 0; i < count; i++)
{
*total += va_arg(numbers, int);
}
va_end(numbers);
}
You can call this function like
...
int result = 0;
add(&result, 3, 10, 20, 30);
...

Resources