C programming function calling to return values - c

I'm a college student in my first year of software engineering. I am in the fourth week of my semester and am having trouble in my programming class. Currently, I was given this assignment in which I was given a function called "getNum()" and I had to use it in another function where the program user, would input a number and the function that I program (must be named isOdd()) would determine if the number is odd or even. Then the main function would print whether the number is odd or even. This is the way that my professor worded it:
" Write a program that uses the getNum() function provided to you in Assignment 2 to get anumber from the user (prompting them first, as always). Create and use a function called isOddwith parameters (the number) and return values (1 ifthe number is odd, 0 if the number is evenOR use a bool or boolean data type, your choice) to determine if thenumber is odd. In main(), tell the user (by displaying using printf()or cout) whether the number is evenor odd."
Now, the problem I am having is understanding programming as I am fairly new to it and some words confuse me, such as parameter and return value. To give you and idea of what I have written so far,
#include <stdio.h>
int isOdd(int numInput);
int getNum(void);
int main(void)
{
int number = 0;
while (number > -1)
{
if (isOdd(0))
{
printf("The number is even.\n");
}
else if (isOdd(1))
{
printf("The number is odd.\n");
}
}
return 0;
}
int isOdd(int numInput)
{
int myNumber = 0;
printf("Please enter a number: ", numInput);
myNumber = getNum();
if (myNumber % 2 == 0)
{
myNumber == 0;
}
else
{
myNumber == 1;
}
return myNumber;
}
#pragma warning(disable: 4996)
int getNum(void)
{
/* the array is 121 bytes in size; we'll see in a later lecture how we can improve this code */
char record[121] = { 0 }; /* record stores the string */
int number = 0;
/* NOTE to student: indent and brace this function consistent with your others */
/* use fgets() to get a string from the keyboard */
fgets(record, 121, stdin);
/* extract the number from the string; sscanf() returns a number
* corresponding with the number of items it found in the string */
if (sscanf(record, "%d", &number) != 1)
{
/* if the user did not enter a number recognizable by
* the system, set number to -1 */
number = -1;
}
return number;
}
This is what I have written, trying to do things accordingly to my professor's instructions, as I do not yet know how to properly use booleans. As you can see, at the bottom is the getNum() function that my professor has said is mandatory for this assignment. As of now, everything I input, I am told is even. I am not asking for you guys to solve and do everything for me but I want to understand what I am doing wrong, what my thinking is doing wrong and to overall better my understanding for future programming. Thank you

It's hard to help you without knowing why you did what you did. A lot of the code is just baffling:
if (isOdd(0))
Why are you passing a zero to isOdd?
printf("Please enter a number: ", numInput);
myNumber = getNum();
Is numInput supposed to be the number they enter or is myNumber supposed to be?
if (myNumber % 2 == 0)
{
myNumber == 0;
}
The statement myNumber == 0 compares myNumber to zero to see if they're equal. It does nothing useful here since you ignore the result of the comparison.

The function:
int getNum(void)
Takes no parameters (void), and returns an integer (int) value. The function itself accepts input from the standard input (stdin) stream - this is normally from the keyboard.
To complete your assignment you should write a function:
int isOdd( int value ) ;
Where value is an integer parameter and the return value is 1 if value is odd and 0 if it is even. Alternatively you are allowed to use the Boolean type:
#include "bool.h"
bool isOdd( int value ) ;
In which case you would return true for odd, and false for even.
Your isOdd() includes the getNumber() call and user prompt code. Not only is that not specified in the assignment, it is poor design making isOdd() difficult to use in more general situations. The assignment explicitly requires you to pass the value to be tested as a parameter.
The assignment does not require you to iterate the test (the while loop is not needed). The user input prompt and acceptance should be in main as follows:
int main(void)
{
printf( "Please enter a number: " ) ;
fflush( stdin ) ; // you'll may this on some platforms
int myNumber = getNum();
if( isOdd( myNumber ) )
{
printf("The number is odd.\n");
}
else
{
printf("The number is even.\n");
}
}
return 0;
}
Note that there are only two possible outcomes, so you do not need an else if( !isOdd( myNumber ) ... - if it is not odd it is implicitly even.
Your isOdd() function will work, but is over complicated. You are required to return a Boolean (a type with two possible values true/false - or an integer 1/0 which can be implicitly converted to a Boolean), and (myNumber % 2 == 0) is a Boolean expression (an expression with two possible results true or false). Anywhere you see the pattern:
if( <boolean expression> )
{
b = true ;
}
else
{
b = false ;
}
you can simply write:
b = <boolean expression> ;
In your case the Boolean determination of odd-ness is simply value % 2 != 0. You can return that directly:
bool isOdd( int value )
{
return value % 2 != 0 ;
}

Related

How to print random even numbers "n" times? Print the number many times mentioned in the output

Can someone help me with this? I want to write a code that will print random even number "i" times. Here "i" is variable and input (i is always greater than 0). Example: Input (4) I want output to be (4,4,4,4), Input (2) I want output to be (2,2). I want to print the number many times mentioned in the input. Here is the question
Here, the term "random" may not be appropriate.
In order to achieve this, you can:
get the numerical representation of the user input. To do so you can use strtol which returns a number.
use a for-loop print the N occurrences using the standard printf function along with the number formatter %d.
For instance:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int number;
int i;
/* `argc` contains the total number of arguments passed to the
* application. There is always at least one argument (i.e.: the
* application name). Here, we ensure the user has given a argument
* which we expect to be the number (i).
*
* If there are less than two arguments given then the user has
* not passed anything => the command line was "$ ./a.out". */
if (argc < 2) {
goto usage;
}
/* Get the user input number by parsing the user given argument.
* As arguments are string of characters, this function transforms
* the string "1234" into 1234. The result is a number we will be
* able to manipulate (add, sub, mul, div, etc.). */
char *endptr;
number = strtol(argv[1], &endptr, 10);
/* We want to ensure the input was really a number.
* The `strtol` function provides a way to verify whether the
* given string is correctly formatted by giving the last character
* of the string. In case the number is not formatted correctly,
* then the last char is not the NULL terminating char. */
if (*endptr != '\0') {
goto usage;
}
/* Ensure the number is positive. */
if (number < 0) {
goto usage;
}
/* This for loop executes "number" of times. We have a counter
* `i` which value will be incremented from [ 0 to "number" [.
* Each time we execute the loop, we print the number. */
for (i = 0; i < number; i++) {
printf("%d ", number);
}
printf("\n");
return 0;
usage:
// TODO
return 1;
}
The easiest way is to read input from the user and just display the number "n" times. Here's an example:
#include <stdio.h>
int main(int argc, char **argv) {
int user_input, is_correct; // user_input is a number to be displayed
// scanf reads input from the user, %d is an integer
is_correct = scanf("%d", &user_input);
// check if user entered a number
if(!is_correct) {
printf("Incorrect input, enter number!");;
return -1;
}
// check if number is even
if(user_input % 2 != 0) {
printf("Number is not even, try again!");
return -1;
}
// display number
for(int i = 0; i < user_input; ++i) {
printf("%d ", user_input);
}
return 0;
}

Printf Statement Runs After Function Goes From 'Void' to 'Int'

I'm new to C.
I've made some code which creates an array, allows for user input to initialise the indexes of the array, and finally the inputs are checked against some parameters.
When I was originally testing the code, the function which contained the verification process was a 'void' function, but since I want this verification function to be the gatekeeper as to whether other functions run in my program, I changed it to an 'int' function so it could return a value which determined whether or not the rest of the program would run.
However, now it returns the printf statement in about invalid inputs twice. When it was a void function it would only display it once. How do I only get the printf statement in 'int verify' to display once?
Expected Input & Output:
1 2 1 3 4 5 } Input
Invalid input: 6 integers 1..9 in sorted order must be supplied. } Output
Current Output:
1 2 1 3 4 5 } Input
Invalid input: 6 integers 1..9 in sorted order must be supplied.}
Invalid input: 6 integers 1..9 in sorted order must be supplied.} Output
#define SIZE 6 //Size of array
void input(int selection[SIZE]);
int verify(int selection[SIZE]);
int main (void){
int selection[SIZE] = {0};
input(selection);
verify(selection);
if (verify(selection) == 1) {
printf("Correct!\n");
}
return 0;
}
//Function which assigns user input into array
void input(int selection[SIZE]){
int i = 0;
while (i < SIZE) {
scanf("%d", &selection[i]);
i++;
}
}
//Function to verify that user's input stays within the bounds
int verify(int selection[SIZE]){
int ver1 = 0;
int ver2 = 0;
int para = 1;
//Checks if inputted numbers are in desired range.
while (ver1 < SIZE) {
if (selection[ver1] > 9 || selection[ver1] < 1) {
printf("Invalid input: 6 integers 1..9 ");
printf("in sorted order must be supplied.\n");
ver2 = SIZE; //Prevents other checks from running as to have duplicate text
ver1 = SIZE; //Prevents other checks from running as to have duplicate text
para = 0;
}
ver1++;
}
//Loops through each value inputed into the function and verifies that
//they are in sorted order
while (ver2 < (SIZE-1)) {
if (selection[ver2] > selection[ver2+1]){
printf("Invalid input: 6 integers 1..9");
printf(" in sorted order must be supplied.\n");
ver2 = SIZE;
para = 0;
}
ver2++;
}
return para;
}
Change this code:
verify(selection);
if (verify(selection) == 1) {
printf("Correct!\n");
}
to this:
if (verify(selection) == 1) {
printf("Correct!\n");
}
Basically, verify was producing output twice because you were calling it twice.
Your code was calling verify twice, causing 'invalid input' to be printed twice.
You called it once before the if, and once inside the if.
If you want to check what the verify function returned, without calling it again, you can write something like this:
int checkResult = verify(selection);
if ( checkResult == 1) {
printf("Correct!\n");

Two integers and an operator. Error, not doing what it needs to do in other compiler

The problem here is that it works on vscode but it doesn't in onlinegdb.com. I think there's some error in my code that I overlook but I can't find so I am hoping someone out there would help me out. thank you very much.
btw there's no warning error in onlinegdb.com but when I try to run it, the result is not right so that's the issue.
#include <stdio.h>
#include <string.h>
//This is a FUNCTION PROTOTYPE :)
int check(char op);
int calculate(int a, int b, int c);
char * print_operators(int op);
int main()
{
// create a variable to store the integers.
int num1,num2;
// create a variable to store the operator that the user wants to use.
char operator;
//prompt for the first integer.
printf("Enter first Integer: ");
scanf("%d", &num1);
// prompt to enter the operator to be used.
do
{
printf("Enter operator, + as sum, - as difference, * as product, / as quotient: ");
scanf(" %s", &operator);
}
// keep prompting the user until he input the correct operator using the check function call.
while(check(operator) == -1);
// prompt for the second integer.
printf("Enter Second Integer: ");
scanf("%d", &num2);
// calculate the total result using the calculate function call and store it to a variable called total.
int total = calculate(num1, num2, check(operator));
// using the print_operators to know what is the operator being used to store it in variable operators in a string form.
char * operators = print_operators(check(operator));
//output of the result.
printf("The %s is: %d\n", operators, total);
return 0;
}
// this is function definition of check to verify if the input is valid and if it's valid then covert it to integer in an order.
int check(char op)
{
// creating a char array to store the symbol of the operators.
char operations[] = {'+', '-', '*', '/'};
// this variable is to be use in a for loop so that I don't need to use a magic number in for-condition.
int size = sizeof(operations);
// looping to convert the operator to integer from 0 to 3 and storing the operator in its ordered form.
// 0 representing +, 1 representing -, 2 representing *, and 3 representing /.
for (int i = 0; i < size; i++)
{
if(op == operations[i])
{
return i;
}
}
// else print invalid and return the value of -1 representing its not valid.
printf("INVALID\n");
return -1;
}
// this function definition of calculating is to calculate the two integers using the operator that is already converted to an integer.
int calculate(int a, int b, int c)
{
// create a variable to store the result of the calculation.
int equal;
// if the operator is 0 then do addition.... and so on.............
if (c == 0)
{
equal = a + b;
}
else if (c == 1)
{
equal = a - b;
}
else if (c == 2)
{
equal = a * b;
}
//else if its not 0, 1, or 2 then its difinitely 3.
else
{
equal = a / b;
}
// then return the result.
return equal;
}
/* This function definition of print_operators is to return the operator as a string so that I can use it in print without manually coding it. */
char * print_operators(int op)
{
char * operators[] = { "sum", "difference", "product", "quotient" };
int size = sizeof(operators);
for (int i = 0; i < size; i++)
{
if (i == op)
{
return operators[i];
}
}
// Some compiler needs a return value even if it didn't reach so I just did this just in case your compiler is different from mine.
//although this is not necessary for my compiler, I've checked it in the cloud server, and there's an error if this is not included.
char * total = "total";
return total;
}
/* Example if I want to output the 1+2 then my output is "The sum is: 3". Notice that the sum is not constant cuz maybe if I what to use subtraction then I want it to output as "The difference is: 1". */
First of all, scanf(" %s", &operator); should be scanf(" %c", &operator); operator because you are expecting a single character here, not a string. It can potentially corrupt the stack.
I guess that should fix your issue with onlinegdb.
There are also other issues and possible simplifications. Such as your print_operators function which may be written simply as:
char *print_operators(int op)
{
char *operators[] = { "sum", "difference", "product", "quotient" };
/* sizeof(array) gives the total size of your array in bytes, not the number of elements in your array, so divide it by the size of each element to get num of elements */
int count = sizeof(operators)/sizeof(char *);
/* Since you already have the operator converted to a number in your check() function, just use it directly as index here */
if(op < count)
return operators[op];
else
return "total";
}
"Some compiler needs a return value"
All compilers need a return value if you have specified that a function returns a value other than void. Some compilers, however, may not warn you that you are not returning a value and lead you into undefined behaviour, which is not what you want.

Infinite loop with scanf in while loop

I'm a very beginner in C, and I'm trying to put a range in the numbers, but the infinite loop appears when a letter out of range is typed (for example: p).
If I type a number out of range, it works.
I read about and I think its a problem with the buffer and the function scanf, when I press "Enter" I include \n. So I tried to clean by scanning with a char, but didn't work.
I also tried to put a space (' ') before the %x, and didn't work.
The scanf it's been ignored after I put an invalid letter; if I put an invalid number, the program works.
#include <stdio.h>
int main()
{
int validity, pos; //validity 0:not valid, repeat the loop; validity 1: valid number
char enter;
while (validity == 0) {
printf("Player1 1, type the position in hexadecimal (1 to f):\n");
scanf(" %x%c", &pos, &enter); //here, the number pos is already in decimal
if (pos == NULL){
pos = 99; //if the letter typed is improper, I set 99, because is out of range
}
if(pos<=15 && pos >=0){
validity = 1;
} else {
printf("Invalid number, out of range\n");
validity = 0;
}
}
}
The very first time in your loop, validity does not have a defined value at all.
It might be 1, it might be 0, it might be 65,532.
You should assign it an initial value.
int validity = 0, pos; //validity 0:not valid, repeat the loop; validity 1: valid number
You declared pos as an int; it will never be NULL. It will have integer values.
This line makes no sense:
if (pos == NULL){
You should initialize that variable as well.
int validity = 0, pos = 99; //validity 0:not valid, repeat the loop; validity 1: valid number
C doesn't have default values for primitive data types. Hence in the line
int validity, pos;
You should probably set validity to some default value like 0 so that the loop runs at least once no matter what the input is(valid or invalid). Alternatively using a do while loop in this situation seems to be a more logical decision.
do
{
//Your code
} while(validity == 0);
In that case you won't have to worry about setting a default value to validity.
Also as #abelenky pointed out earlier, checking pos for NULL is a technically bad idea as well. You could as well just skip this part
if (pos == NULL)
{
pos = 99;
}
As pos is declared to be int, if the value of pos doesn't lie between 0 and 15 then it is automatically declared invalid by this part of your code.
if(pos<=15 && pos >=0)
{
validity = 1;
}
else
{
printf("Invalid number, out of range\n");
validity = 0;
}
Hence there is no need to make another block for checking it's validity.
The cause of the infinite loop is that if you input a letter, the "\n" that follows it is taken as the input of scanf(...) function within the next loop. So you can simply add "getchar()" to fix it. Note the ā€œ\nā€ after a number is ignored.
Differently, when you type a number out of range, it can be resolve with hex, and you can print it to see. But the letter can't(must be between a-f).
You can reference this:
#include <stdio.h>
int main(int argc, char *argv[])
{
int validity=0, pos=99;
while (validity == 0){
printf("Player1 1, type the position in hexadecimal (1 to f):\n");
scanf("%x", &pos);
if(pos<=15 && pos >=0){
validity = 1;
}else {
printf("Invalid number, out of range\n");
getchar();
}
}
}
Good luck.

How to scan in values and ignore the characters

I am a newbie to C and I was looking over some questions where I pondered upon a question where we need to scan in values using the users input. Example
1 2 3 45 6 7. So Automatically we scan these values into a 2D array.
One thing that troubles me is what If the user inputs
1 2 3 2 3 Josh, how can we ignore Josh and only scan in the values into the array.
I looked at using getchar and use a flag variable but I am unable to figure out the conundrum of differentiating between the integer and character.
/* This is something that I tried */
#include <stdio.h>
int main(int argc, char *argv[]) {
int a;
int b;
int A[10];
while (((a = getchar()) != '\n') && (b = 0)) {
if (!(a >= "A" && a <= "Z")) {
scanf("%d", A[b]);
}
b++;
}
}
}
I think one good method for achieving what you want is using scanf with the format "%s", which will read everything as a string, effectively splitting the input according to white spaces. From the manual:
s
Matches a sequence of non-white-space characters; the next
pointer must be a pointer to character array that is long
enough to hold the input sequence and the terminating null
byte ('\0'), which is added automatically. The input string
stops at white space or at the maximum field width, whichever
occurs first.
To convert the string to integer, you can use atoi. From the manual:
The atoi() function converts the initial portion of the string
pointed to by nptr to int.
So, if it converts the initial portion of the string into an integer, we can use that to identify what is a number and what's not.
You can build a simple "word detector" for atoi.
Using the function isalpha from ctype.h you can do:
int isword(char *buffer)
{
return isalpha(*buffer);
}
And rewriting your reading program you have:
#include <stdio.h>
#include <ctype.h>
int isword(char *buffer)
{
return isalpha(*buffer);
}
int main(void)
{
char input[200];
int num;
while (1) {
scanf("%s", input);
if (!strcmp(input, "exit")) break;
if (isword(input)) continue;
num = atoi(input);
printf("Got number: %d\n", num);
}
return 0;
}
You should keep in mind that the name isword is fallacious. This function will not detect if buffer is, in fact, a word. It only tests the first character and if that is a character it returns true. The reason for this is the way our base function itoa works. It will return zero if the first character of the buffer is not a number - and that's not what you want. So, if you have other needs, you can use this function as a base.
That's also the reason I wrote a separate function and not:
if (!isalpha(input[0]))
num = itoa(input);
else
continue;
The output (with your input):
$ ./draft
1 2 3 2 3 Josh
Got number: 1
Got number: 2
Got number: 3
Got number: 2
Got number: 3
exit
$
About assigments and &&
while (((a = getchar()) != '\n') && (b = 0))
As I said in a comment, this loop will never work because you're making a logical conjunction(AND) with an assignment that will always return zero. That means the loop condition will always evaluate to false.
In C, assignments return the value assigned. So, if you do
int a = (b = 10);
a will have now hold the value 10. In the same way, when you do
something && (b = 0)
You're effectively doing
something && 0
Which will always evaluate to false (if you remember the AND truth table):
p q p && q
---------------
0 0 0
0 1 0
1 0 0
1 1 1
Your code is completely wrong. I suggest to delete it.
You could use scanf with %d to read in numbers. If it returns 0, there is some invalid input. So, scan and discard a %s and repeat this process:
int num = -1;
while(num != 0)
{
printf("Enter a number, enter 0 to exit:");
if(scanf("%d", &num) == 0) /* If scanf failed */
{
printf("Invalid input found!");
scanf("%*s"); /* Get rid of the invalid input (a word) */
}
}

Resources