If character then redo the function - c

In C code.
This is the part I want to work on below. I want to be able to do... if a character value then say "not a number", however, because it is an array and it increments I'm not sure how to do such, newbie here, so please explain and show me an example how to do if possible. Have to enter up to 10 values.
So if:
Employee 1 = c
"Not a Number. Try again."
Employee 1 = 5
Employee 2 = 55
Employee 3 = g
"Not a Number. Try again."
Employee 3...etc
void getSalaries(float sal[], int size)
{
int i = 0;
for(i = 0; i < size; i++)
{
printf("Enter salary for Employee #%d: ", i + 1);
if (scanf("%f", &sal[i]) != 1)
{
printf ("Not a number. Please try again.\n");
break;
}
}
}

If you want to repeat something, you need a loop. If you don't know how many times you'll want to loop in advance, it's probably going to be a while loop. The following structure will achieve your goal cleanly:
while (1) {
printf("Enter salary for Employee #%d: ", i + 1);
scanf("%f", &sal[i]);
if (...valid...)
break;
printf("Not a Number. Try again.\n");
}
The value returned by scanf will help you determine if the input was valid. I will leave consulting the documentation and finishing that part of your homework to you.

Some help to get you started, scanf returns the number of successfully read items (matching % marks in format string). So you can evaluate this number and take action accordingly.
int n=scanf("%f", &sal[i]);
if (n !=1){
// do something here
}
Hint: There is a common problem with using scanf,in that it wont recover from a "bad" input, unless you empty the buffer by "eating" the bad string.
If you want to convince your teacher that you have a VERY BIG BRAIN /s, you could do something like this;
#include <stdio.h>
#include <string.h>
void getSalaries (float sal[], int size)
{
char *scan_fmt[2] = {
"%f", // Get float
"%*s%f" // Eat previous bad input, and get float
};
char *cli_mess[2] = {
"Enter salary for Employee #%d: ",
"Try again, for Employee #%d: "
};
for (int i = 0, n=1; i < size; i += n==1){
printf (cli_mess[n!=1], i + 1);
n = scanf (scan_fmt[n!=1], &sal[i]);
}
}
int main ()
{
float s[3];
getSalaries (s, 3);
return 0;
}

Related

Some problems in coding a "guessing random number in C" under some conditions such as using input(), output()

I tried going beyond just guessing random numbers. The conditions were these:
use input() numbers used from 1 to100 and if inserted numbers that are out of this range, to show a line to re-enter a number
use output() to show the output(but show the last line```You got it right on your Nth try!" on the main())
make the inserted number keep showing on the next line.
Basically, the program should be made to show like this :
insert a number : 70
bigger than 0 smaller than 70.
insert a number : 35
bigger than 35 smaller than 70.
insert a number : 55
bigger than 55 smaller than 70.
insert a number : 60
bigger than 55 smaller than 60.
insert a number : 57
You got it right on your 5th try!
I've been working on this already for 6 hours now...(since I'm a beginner)... and thankfully I've been able to manage to get the basic structure so that the program would at least be able to show whether the number is bigger than the inserted number of smaller than the inserted number.
The problem is, I am unable to get the numbers to be keep showing on the line. For example, I can't the inserted number 70 keep showing on smaller than 70.
Also, I am unable to find out how to get the number of how many tries have been made. I first tried to put it in the input() as count = 0 ... count++; but failed in the output. Then I tried to put in in the output(), but the output wouldn't return the count so I failed again.
I hope to get advice on this problem.
The following is the code that I wrote that has no errors, but problems in that it doesn't match the conditions of the final outcome.
(By the way, I'm currently using Visual Studio 2017 which is why there is a line of #pragma warning (disable : 4996), and myflush instead of fflush.)
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)
int input();
int random(int);
void myflush();
void output(int, int);
int main()
{
int num;
int i;
int ran;
srand((unsigned int)time(NULL));
i = 0;
while (i < 1) {
ran = 1 + random(101);
++i;
}
num = input();
output(ran, num);
printf("You got it right on your th try!");a
return 0;
}
int input()
{
int num;
printf("insert a number : ");
scanf("%d", &num);
while (num < 1 || num > 100 || getchar() != '\n') {
myflush();
printf("insert a number : ");
scanf("%d", &num);
}
return num;
}
int random(int n)
{
int res;
res = rand() % n;
return res;
}
void myflush()
{
while (getchar() != '\n') {
;
}
return;
}
void output(int ran, int num) {
while (1) {
if (num != ran){
if (num < ran) {
printf("bigger than %d \n", num); //
}
else if (num > ran) {
printf("smaller than %d.\n", num);
}
printf("insert a number : ");
scanf("%d", &num);
}
else {
break;
}
}
return;
}
There are many problem and possible simplifications in this code.
use fgets to read a line then scanf the line content. This avoids the need of myflush which doesn’t work properly.
the function random is not needed since picking a random number is a simple expression.
if the range of the random number is [1,100], you should use 1+rand()%100.
there is no real need for the function output since it’s the core of the main program. The input function is however good to keep to encapsulate input.
you should test the return value of scanf because the input may not always contain a number.
Here is a simplified code that provides the desired output.
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)
int input() {
char line[100];
int num, nVal;
printf("insert a number : ");
fgets(line, sizeof line, stdin);
nVal = sscanf(line, "%d", &num);
while (nVal != 1 || num < 1 || num > 100) {
printf("insert a number : ");
fgets(line, sizeof line, stdin);
nVal = sscanf(line, "%d", &num);
}
return num;
}
int main()
{
int cnt = 0, lowerLimit = 0, upperLimit = 101;
srand((unsigned int)time(NULL));
// pick a random number in the range [1,100]
int ran = 1 + rand()%100;
while(1) {
cnt++;
int num = input();
if (num == ran)
break;
if (num > lowerLimit && num < upperLimit) {
if (num < ran)
lowerLimit = num;
else
upperLimit = num;
}
printf("bigger than %d and smaller than %d\n", lowerLimit, upperLimit);
}
printf("You got it right on your %dth try!\n", cnt);
return 0;
}
I am unable to find out how to get the number of how many tries have been made.
Change the output function from void to int so it can return a value for count, and note comments for other changes:
int output(int ran, int num) {//changed from void to int
int count = 0;//create a variable to track tries
while (1) {
if (num != ran){
count++;//increment tries here and...
if (num < ran) {
printf("bigger than %d \n", num); //
}
else if (num > ran) {
printf("smaller than %d.\n", num);
}
printf("insert a number : ");
scanf("%d", &num);
}
else {
count++;//... here
break;
}
}
return count;//return value for accumulated tries
}
Then in main:
//declare count
int count = 0;
...
count = output(ran, num);
printf("You got it right on your %dth try!", count);
With these modifications, your code ran as you described above.
(However, th doesn't work so well though for the 1st, 2nd or 3rd tries)
If you want the program to always display the highest entered number that is lower than the random number ("bigger than") and the lowest entered number that is higher then the random number ("smaller than"), then your program must remember these two numbers so it can update and print them as necessary.
In the function main, you could declare the following two ints:
int bigger_than, smaller_than;
These variables must go into the function main, because these numbers must be remembered for the entire duration of the program. The function main is the only function which runs for the entire program, all other functions only run for a short time. An alternative would be to declare these two variables as global. However, that is considered bad programming style.
These variables will of course have to be updated when the user enters a new number.
These two ints would have to be passed to the function output every time it is called, increasing the number of parameters of this function from 2 to 4.
If you want a counter to count the number of numbers entered, you will also have to remember this value in the function main (or as a global variable) and pass it to the function output. This will increase the number of parameters for the function to 5.
If you don't want to pass so many parameters to output, you could merge the contents of the functions output and input into the function main.
However, either way, you will have to move most of the "smaller than" and "bigger than" logic from the function output into the function main, because that logic is required for changing the new "bigger_than" and "smaller_than" int variables which belong to the function main. The function output should only contain the actual printing logic.
Although it is technically possible to change these two variables that belong to the function main from inside the function output, I don't recommend it, because that would get messy. It would require you to pass several pointers to the function output, which would allow that function to change the variables that belong to the function main.
I have now written my own solution and I found that it is much easier to write by merging the function output into main. I also merged all the other functions into main, but that wasn't as important as merging the function output.
Here is my code:
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)
int main()
{
const char *ordinals[4] = { "st", "nd", "rd", "th" };
int num_tries = 0;
int bigger_than = 0, smaller_than = 101;
int input_num;
int random_num;
srand( (unsigned int)time( NULL ) );
random_num = 1 + rand() % 101;
for (;;) //infinite loop, equivalent to while(1)
{
printf( "Bigger than: %d, Smaller than: %d\n", bigger_than, smaller_than );
printf( "enter a number: " );
scanf( "%d", &input_num );
printf( "You entered: %d\n", input_num );
num_tries++;
if ( input_num == random_num ) break;
if ( input_num < random_num )
{
if ( bigger_than < input_num )
{
bigger_than = input_num;
}
}
else
{
if ( smaller_than > input_num )
{
smaller_than = input_num;
}
}
}
printf( "You got it right on your %d%s try!", num_tries, ordinals[num_tries<3?num_tries:3] );
return 0;
}
Also, I made sure that the program would print "1st", "2nd" and "3rd", whereas all the other solutions simply print "1th", "2th", "3th". I used the c++ conditional operator for this.

Partial array output includes garbage

Most of my experience is limited to SQL scripting for DBA functions. I am a security specialist and provide help to others on those topics, but I am learning C to aid in those other endeavors. I've been reading books, writing small programs, and expanding the difficulty level as I go. This is the first time I've had to reach out for help. I apologize if this has been asked, but I did search first and didn't find anything.
So far, my programs have always returned only the valid data from partially filled arrays. This particular one is not behaving the same even though I'm using the same for statement I have previously used with success. At this point I must have tunnel vision because I cannot seem to see where this is failing.
If there are fewer than 20 inputs, the printf output displays the remaining values with garbage. It would be greatly appreciated if someone could provide some guidance on what I'm overlooking. Thank you in advance.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct grade
{
int id;
int percent;
};
#define maxCount 100
int main()
{
int *grade;
struct grade gradeBook[maxCount];
int count = 0;
char YN;
int i;
for(i = 0; i < maxCount; i++)
{
printf("Enter ID: ");
scanf("%d", &gradeBook[i].id);
printf("Enter grade from 0-100: ");
scanf("%d", &gradeBook[i].percent);
count++;
// Prompt to continue, break if done
printf("Do you want to Continue? (Y/N)");
scanf(" %c", &YN);
if(YN == 'n' || YN == 'N')
{
break;
}
}
void sort(struct grade gradeBook[],int cnt)
{
int i, j;
struct grade temp;
for (i = 0; i < (cnt - 1); i++)
{
for (j = (i + 1); j < cnt; j++)
{
if(gradeBook[j].id < gradeBook[i].id)
{
temp = gradeBook[j];
gradeBook[j] = gradeBook[i];
gradeBook[i] = temp;
}
}
}
}
printf("Grades entered and ordered by ID: \n");
for (i = 0; i < count; i++)
{
printf("\nID:%d, Grade: %3d\n", gradeBook[i].id,gradeBook[i].percent);
}
return 0;
}
If there are fewer than 20 inputs, the printf output displays the remaining values with garbage
What else did you expect?
If you have fewer than 20 inputs, then the remaining inputs have not been given any value. You say "partial array input" but you literally asked the computer to loop over the entire array.
It's really not clear what else you expected to happen here.
Perhaps loop to count the second time instead.

Can I check a condition for one variable

I am writing a program to scan the name, gender, and three monthly checks for a person. Here is an example on what I want entered:
Jack m 200 250 300
If the user types "Enough" and presses enter without filling the other details I want the loop to end. I tried using two scanf's, one for the string alone and one for the others but it doesn't loop properly. Here is my code:
int main()
{
int i;
char names[SIZE][NAME_LEN] = {0}, gender[SIZE] = {0};
int sales[SIZE][SALES_LEN] = {0};
printf("Enter the name, gender and three month sales for name %d: ", i+1);
for (i=0; i<SIZE; i++){
if (strcmp(names[i], "Enough") == 0 || strcmp(names[i], "enough") == 0)
break;
scanf("%s %c %d %d %d",names[i], &gender[i], &sales[i][0],&sales[i][1],&sales[i][2]);
}
return 0;
}
Your code is broken is many places: badly ordered statements and wrong kind of reading and parsing. This may do the trick:
for (i=0; i<SIZE; i++) {
char buffer[100]; // A full line
printf("Enter the name, gender and three month sales for name %d: ", i+1);
if (fgets(buffer,sizeof buffer,stdin)==NULL // if nothing can be read
|| strncasecmp(buffer,"-stop",5)) { // or if user typed "-stop" and whatever, an impossible lastname?
break;
}
// try to convert the line into fields of given types...
if (sscanf(buffer,"%s %c %d %d %d",names[i], &gender[i], &sales[i][0],&sales[i][1],&sales[i][2])!=5) {
// do something if conversions failed
}
}
You could use something like this:
while(gets(line)) { ... }
If user presses only the return key the gets function returns NULL and the cycle stops. This way the user doesn't have to type "Enough".
*Don't use the gets() function because it's unsafe (risk of buffer overflow).
I usually wrap it in a function which controls the length of the input.

Write a program that multiplies user entered number till product of these numbers reach 1000

I've trying to do it for about an hour, but I can't seem to get it right. How is it done?
The code I have at the moment is:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int j=-1;
while(j<0){
printf("Enter a number: \n");
scanf("%d", &j);
}
int i=j;
for(i=j; i<=100; i++){
printf("%d \n", i);
}
return 0;
}
The original specification (before code was added) was a little vague but, in terms of the process to follow, that's irrelevant. Let's assume they're as follows:
get two numbers from the user.
if their product is greater than a thousand, print it and stop.
otherwise, print product and go back to first bullet point.
(if that's not quite what you're after, the process is still the same, you just have to adjust the individual steps).
Translating that in to pseudo-code is often a first good step when developing. That would give you something like:
def program:
set product to -1
while product <= 1000:
print prompt asking for numbers
get num1 and num2 from user
set product to num1 * num2
print product
print "target reached"
From that point, it's a matter of converting the pseudo-code into a formal computer language, which is generally close to a one-to-one mapping operation.
A good first attempt would be along the lines of:
#include <stdio.h>
int main (void) {
int num1, num2, product = -1;
while (product < 1000) {
printf ("Please enter two whole numbers, separated by a space: ");
scanf ("%d %d", &num1, &num2);
product = num1 * num2;
printf ("Product is %d\n", product);
}
puts ("Target reached");
return 0;
}
although there will no doubt be problems with this since it doesn't robustly handle invalid input. However, at the level you're operating, it would be a good start.
In terms of the code you've supplied (which probably should have been in the original question, though I've added it now):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int j=-1;
while(j<0){
printf("Enter a number: \n");
scanf("%d", &j);
}
int i=j;
for(i=j; i<=100; i++){
printf("%d \n", i);
}
return 0;
}
a better way to do the final loop would be along the lines of:
int i = 1;
while (i < 1000) {
i = i * j;
printf ("%n\n", i);
}
This uses the correct terminating condition of the multiplied number being a thousand or more rather than what you had, a fixed number of multiplications.
You may also want to catch the possibility that the user enters one, which would result in an infinite loop.
A (relatively) professional program to do this would be similar to:
#include <stdio.h>
int main (void) {
// Get starting point, two or more.
int start = 0;
while (start < 2) {
printf("Enter a number greater than one: ");
if (scanf("%d", &start) != 1) {
// No integer available, clear to end of input line.
for (int ch = 0; ch != '\n'; ch = getchar());
}
}
// Start with one, continue while less than a thousand.
int curr = 1;
while (curr < 1000) {
// Multiply then print.
curr *= start;
printf ("%d\n", curr);
}
return 0;
}
This has the following features:
more suitable variable names.
detection and repair of most invalid input.
comments.
That code is included just as an educational example showing how to do a reasonably good job. If you use it as-is for your classwork, don't be surprised if your educators fail you for plagiarism. I'm pretty certain most of them would be using web-search tools to detect that sort of stuff.
I'm not 100% clear on what you are asking for so I'm assuming the following that you want to get user to keep on entering numbers (I've assumed positive integers) until the all of them multiplied together is greater than or equal to 1000).
The code here starts with the value 1 (because starting with 0 will mean it will never get to anything other than 0) and multiples positive integers to it while the product of all of them remains under 1000. Finally it prints the total (which may be over 1000) and also the number of values entered by the user.
I hope this helps.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char input[10];
unsigned currentTotal = 1;
unsigned value;
unsigned numEntered = 0;
while( currentTotal < 1000 )
{
printf( "Enter a number: \n" );
fgets( input, sizeof(input), stdin );
value = atoi( input );
if( value > 0 )
{
currentTotal *= value;
numEntered += 1;
}
else
{
printf( "Please enter a positive integer value\n" );
}
}
printf( "You entered %u numbers which when multiplied together equal %u\n", numEntered, currentTotal );
return 0;
}
Try this one:
#include <stdio.h>
int main()
{
int input,output=1;
while(1)
{
scanf("%d",&input);
if(input<=0)
printf("Please enter a positive integer not less than 1 :\n");
else if(input>0)
output*=input;
if(output>1000)
{
printf("\nThe result is: %d",output);
break;
}
}
return 0;
}

Need function to find largest value in an array, return it to main( ) and print out

To me, my program looks like it should do what I want it to do: prompt a user to enter 10 values for an array, then find the largest of those values in the array using a function, then return the largest number to the main () function and print it out.
But, when I enter values, I never get numbers back that look anything like the ones I'm entering.
For example, let's say I enter just "10, 11" I get back "1606416648 = largest value".
Does anyone know what I'm doing wrong?
Here's the code:
#include <stdio.h>
#define LIMIT 10
int largest(int pointer[]);
int main(void)
{
int str[LIMIT];
int max;
int i = 0;
printf("Please enter 10 integer values:\n");
while (i < LIMIT)
{
scanf("%d", &str[i]);
i++;
}
// Thanks for your help, I've been able to make the program work with the above edit!
max = largest(str);
printf("%d = largest value\n", max);
return 0;
}
int largest(int pointer[])
{
int i;
int max = pointer[0];
for (i = 1; i < LIMIT; i++)
{
if (max < pointer[i])
max = pointer[i];
}
return max;
}
scanf("%d", &str[LIMIT]); reads in one number and puts it in the memory location one past the end of your array.
After changes:
You don't need scanf() in your while condition; it should go in the while body instead.
Your scanf() still isn't quite right. You need to tell it where in the array you want to store the input.
str[i]; doesn't do anything.
printf("Please enter 10 integer values:\n");
scanf("%d", &str[LIMIT]);
This doesn't do what you think. First, it only reads one number in. Second, you are reading it into the last position + 1 of the array.

Resources