Return Value Function in C - c

Hello I'm working on a quick program that generates a master code and the user has to guess the code. When checking the user's guess I use 2 functions one for Exact Matches and the other for close matches (where they got a number that's in the mastercode but not in the right location)
Ex. master code 1 2 3 4
user 2 3 2 4
the output the should show the user has 2 close matches and one exact match. I'm having trouble understanding how to properly return an int.
My ouput just shows the default value of exactMatch and closeMatch when I try to print them in Main. any insight will be greatly appreciated. Thank you.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define CODELENGTH 4
#define NUMSYMBOLS 6
int MasterCode[4];
int guess[ 4 ];
int exactMatch;
int closeMatch=0;
void genCode (int MasterCode[])
{
int i=0;
int k;
while (i < CODELENGTH){
MasterCode[i] =rand() %NUMSYMBOLS +1;
i++;
}//end while loop.
for ( k = 0 ; k < 4; k++ ) {
printf( "%d ", MasterCode[ k ] );
}
printf( "\n" );
}
void getGuess (int guess[])
{
int number = 0;
printf( "Please enter your list of 4 numbers between 1 and 6: " );
int j;
int k;
for ( j = 0 ; j < 4; j++ ) {
scanf( "%d", &number );
guess[ j ] = number;
}
printf( "Your array has these values: " );
for ( k = 0 ; k < 4; k++ ) {
printf( "%d ", guess[ k ] );
}
printf( "\n" );
}
int main (int argc, char **argv)
{
srand ( time(NULL) );
genCode(MasterCode);
getGuess(guess);
checkExactMatches(MasterCode, guess, exactMatch);
checkCloseMatches(MasterCode, guess, closeMatch);
printf("%d = Ending exactMatches \n", exactMatch);
printf("%d = Ending closeMatches \n", closeMatch);
}
int checkExactMatches (int MasterCode[], int guess[], int exactMatch )
{
int woot;
for(woot=0; woot<4; woot++){
if (MasterCode[woot] == guess[woot]){
printf("Exact Match found \n");
exactMatch ++;
printf( "%d = Guess \n" , guess[ woot ]);
printf( "%d = MasterCode \n", MasterCode[ woot ]);
printf("%d = exactMatch \n", exactMatch);
}// end if
if (MasterCode[woot] != guess[woot])
printf("No EXACT match \n");
}//end for loop
return exactMatch;
} // end checkExactMatches
int checkCloseMatches (int MasterCode[], int guess[], int closeMatch )
{
int k;
int j;
for(k=0; k<4; k++){
for (j=0; j<4; j++) {
if (MasterCode[k] == guess[j]){
printf("CLOSE Match found \n");
closeMatch ++;
printf( "%d = Guess \n" , guess[ j ]);
printf( "%d = MasterCode \n \n", MasterCode[ k ]);
printf("%d = closeMatch \n \n", closeMatch);
}// end if
if (MasterCode[k] != guess[j])
printf("No CLOSE match \n");
}//end nested for loop
}//end for loop
return closeMatch;
} // end checkCloseMatches

Getting the value returned from a function is actually really easy, it's basically the same as assigning a value to a variable. In your case, the syntax would be something like this:
int result = checkExactMatches(MasterCode, guess, exactMatch);
result will now hold the value returned by the function.

What you need to do is
Not pass the count arguments to the function and
Instead collect the return value of the function in the count
So
checkExactMatches(MasterCode, guess, exactMatch);
becomes
exactMatch = checkExactMatches(MasterCode, guess);
You need to make appropriate changes to the function header and also avoid using global variables.

Note that while arrays are passed by pointer (meaning that the function can modify the pointed-to pointer), ints are passed by value. Therefore, changes to the int within a function only persist for the duration of the function.
You want to use
exactMatch = checkExactMatches(MasterCode, guess);
and in that case you won't have to pass in exactMatch any more.

C passes arguments by value, rather than by reference, so passing int exactmatch into the function creates a duplicate of the data inside exactmatch, so operations done inside the method don't do anything.
What you want to do is remove exactmatch from the argument list, and instead assign it as zero (int exactmatch=0; at the beginning of the method, remove exactmatch from the global variables, and use something like int resultExact = checkExactMatches(MasterCode, guess); as your function call. You're already returning the answer correctly, you just don't pick up that answer anywhere.

Related

How do you delete the comma after the number?

So I have this exercise from my Coding class and we were tasked to input the user's input. However, we have to remove the comma of the last number of our output, and I'm struggling with how to remove that comma. Can anyone please help?
this is my code
#include <stdio.h>
#define MAX_SIZE 100
int main(){
int arr[MAX_SIZE];
int N, i;
int * ptr = arr;
printf("Enter length: ");
scanf("%d", &N);
for (i = 0; i < N; i++){
printf("Enter element %d: ", i+1);
scanf("%d", ptr);
ptr++;
}
ptr = arr;
printf("[");
for (i = 0; i < N; i++)
{
printf("%d,", *ptr);
ptr++;
}
printf("]");
return 0;
}
for convenience, this is the output I got
Enter length: 5
Enter element 1: 1
Enter element 2: 2
Enter element 3: 3
Enter element 4: 4
Enter element 5: 5
[1,2,3,4,5,]
this is how the output should be
Enter length: 5
Enter element 1: 1
Enter element 2: 2
Enter element 3: 3
Enter element 4: 4
Enter element 5: 5
[1,2,3,4,5]
Simple:
const char *sep = "";
printf( "[" );
for( i = 0; i < N; i++ ) {
printf( "%s%d", sep, arr[ i ] );
sep = ",";
}
printf( "]" );
Put the commas BEFORE the next value to be printed.
Specify the "prefix" to be "", until that is changed to ","
You'd be better off using "array indexing" throughout instead of shifting a pointer around the place... Too easy to forget to reset it to the beginning...
AND, add some code to check that scanf has assigned an integer value to the uninitialised variable 'N'! If the user types "four" in response to the first prompt, the value of N could be anything, even 243,478,658.... That's a LOT of data to be entering... In addition, the code should also check if the user types 120 to fill the 100 elements of the array.
EDIT: In this instance (surrounding brackets), we can even eliminate one line of code.
const char *sep = "[";
for( i = 0; i < N; i++ ) {
printf( "%s%d", sep, arr[ i ] );
sep = ",";
}
printf( "]" );
and then go on to please the "brace-o-phobes" by changing things around
i = 0;
for( char pre = '['; i < N; pre = ',' )
printf( "%c%d", pre, arr[ i++ ] );
putchar( ']' );
You can use a simple ternary to control the format-string in printf, e.g.
for (i = 0; i < N; i++)
{
printf(i ? ",%d" : "%d", *ptr);
ptr++;
}
That only prints a comma before the number for numbers after the first. An equivalent long-form using if-else would be:
for (i = 0; i < N; i++)
{
if (i) {
printf(",%d", *ptr);
}
else {
printf("%d", *ptr);
}
ptr++;
}
Also suggest the final puts ("]"); to ensure your program is POSIX compliant -- outputting a final '\n' before program exit. Likewise, there is no need to call the variadic printf() function to output a single-character. A simple putchar ('['); will do.

How to break a while loop when it is false to a certain condition

I was trying to make a program where if I enter an integer, the program would find out the bigger number and subtract it by the smaller number. This part, I got it.
The problem is, the infinite loop part.
I tried to get type in two integers keep on printing with the while loop, and break when at least one character is typed in.
For example, if I type in 2 #, it would break.
But I couldn't find the write place to get the break; within the code and therefore whenever I enter a character it would keep on creating an infinite loop.
Is there any way to create a break in this code? I humbly ask for advice...
The following is the code which I couldn't put the break
(By the way, the reason I did the condition in while as sizeof(i)==4 || sizeof(j)==4 was to make it so it would only enter an integer, since the size of an integer is 4)
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i){
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
The bottom code is the one I tried to put break but failed (it kept creating an infinite loop)...
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
if (sizeof(i) == 4 || sizeof(j) == 4) {
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
else
break;
}
return 0;
}
and here's a code where I got rid of the sizeof and used while(1), though there wasn't much change in the fact that the break didn't work...
int main()
{
int i, j;
int result;
while (1){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
You can't use sizeof(i) to do run-time checks! This is a compile-time constant that, in your case (32-bit integers) will always evaluate to 4.
In order to check that two valid integers have been given, you can check the return value of the scanf function (it gives the number of fields successfully scanned):
#include <stdio.h>
int main()
{
int i, j;
int result;
while (1) {
printf("type in two integers : ");
if (scanf("%d %d", &i, &j) != 2) break; // Break here if we didn't get two integers
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
Feel free to ask fir further clarification and/or explanation.
Drop the whole concept of endless loop with break inside if.
Make a condition for the loop based on the return value of scanf(), that is practically what it is designed for.
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
printf("type in two integers : ");
while (2==scanf("%d %d", &i, &j))
{
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
printf("%d\n", result);
printf("type in two integers : ");
}
return 0;
}
I'd probably actually use do {...} while (...) with a variable storing the return value of scanf()for being used in the loop condition. I'd consider it more elegant for not having to copy the print, but I kept it closer to your code structure.
More comments on your code:
as explained in comments, sizeof() works differently than you seem to think; it is static and does not change at runtime and hence cannot be used in a loop condition
with while (sizeof(i)==4 || sizeof(j)==4){if (sizeof(i) == 4 || sizeof(j) == 4){/* a */} else {/* b */}, b cannot ever be reached, because the conditions of while and if are identical
check the possible outcomes of the if conditions inside the loop, you are leaving the one with i==j undefined and return an uninitialised value
always init all variables as a habit
for a good MRE include the include lines
On your request, here is a proposal for the do-while alternative:
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
int iScanned=0;
do
{
printf("type in two integers : ");
iScanned=scanf("%d %d", &i, &j); /* keep the return value for loop */
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
if(2==iScanned) printf("%d\n", result); /* if to avoid awkward last output */
} while (2==iScanned);
return 0;
}

Why isn't this C code's \t working?

I am trying to print a pattern of numbers. Try running this code with a input of 20, you will see that the tab spaces are all in the wrong place, they don't follow the order. I know that the tab spaces jump to the next header, but is there a way to avoid it?
#include <stdio.h>
int main()
{
int i, n, count = 0;
scanf("%d", &n);
for(i = 1; i <= n; i++)
{
printf("%dnumber\t", i);
count++;
if(count == 4)
{
count = 0;
printf("\n");
}
}
return 0;
}
Note: Is there a way to do this with tab spaces only(i.e., "\t" only) instead of using an ordinary white space.
Here is the output that I am getting.
But what I want is this
There are several different problems here.
But it sounds like your main question is "gee: the tabs don't line up like I expect."
SUGGESTED ALTERNATIVE:
Consider using "field length specifiers" in printf():
http://www.cplusplus.com/reference/cstdio/printf/
EXAMPLE:
printf ("%-20s", mystring); // Will always be exactly 20 characters
printf ("%06d", myint); // 6-digits, zero filled
Why not:
#include <stdio.h>
int main( void )
{
int i = 0;
int n = 0;
scanf( "%d", &n );
for( i = 1; i <= n; i++ )
{
printf( "%02dnumber\t", i );
if( i % 4 == 0 )
printf("\n");
}
return 0;
}
Output:
16
01number 02number 03number 04number
05number 06number 07number 08number
09number 10number 11number 12number
13number 14number 15number 16number
Hope it helps!

Average of # Sequence

I'm having trouble figuring out the loop in the average function. User enters sequence and if the number of numbers in the sequence is greater than 0, output avg of the numbers and repeat for another sequence. If the sequence has no numbers, exit program.
I understand that I'm telling the average function to return 0 when sum = 0 and that's why it exits after the 1st sequence (I think).
Any suggestions as to how to avoid that? Pseudocode if possible!
#include<stdio.h>
#include<stdlib.h>
double average();
int main ()
{
while( average() )
{
}
}//end main
double average()
{
double n, sum = 0;
int count = 0;
printf ( "Enter sequence: " );
while( scanf( "%lf", &n ) )
{
sum += n;
count++;
}
if( sum > 0 )
{
printf( "average is %.2f\n", sum/(double)count );
return 1;
}
else
return 0;
}
}
Here is my output:
Enter sequence: 3 4 5 x
average: 4.00
Enter sequence: Press any key to continue . . .
#include <stdio.h>
#include <stdlib.h>
int average(void);
int main(void)
{
while (average())
;
return 0;
}
int average(void)
{
double n, sum = 0;
int count = 0;
printf("Enter sequence: ");
while (scanf( "%lf", &n ) == 1)
{
sum += n;
count++;
}
int c;
while ((c = getchar()) != EOF && c != '\n')
;
if (sum > 0)
{
printf("average is %.2f\n", sum / count);
return 1;
}
else
return 0;
}
This reads anything on the line up to the newline after a conversion fails, thus setting you up for reading the next sequence. The loop test for scanf() is improved; it will exit on EOF, too. The cast in the division was unnecessary; the compiler has to convert count to double because sum is a double, even without you telling it to do so explicitly. The return type of average() is not a double; it is a boolean, which is classically spelled int. In C99 or later (which the code assumes you have; if you don't, you're stuck on Windows and need to move int c; to the top of the function), then you could #include <stdbool.h> and use a return type of bool and replace return 1; by return true; and replace return 0; by return false;.
I think you can initially get input for the variable named count asking for the user to enter the total no of numbers in sequence,and then get those values in sequence.
And if the count is 0,then exit the program.. else continue finding average.
This is because in your case, you have to enter a non numeric char each time to end the sequence.
Well I ended up with this and its working perfectly:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
double average();
int main () {
while( average() ) {}
}//end main
double average() {
double n, sum = 0;
int count = 0;
printf ( "Enter sequence: " );
getchar();
while( scanf( "%lf", &n ) ){
sum += n;
count++;
}//end while
if( n > 0 ){
printf( " average: %.2f\n", sum/(double)count );
return 1;
}//end if
else
return 0;
}//end function

Using command line in C to detect arguments, and then print out the first or second char of the arguments

I need to make a program that accepts no less than 2 and no more than 6 arguments at the command line and then prints out the 1st or 2nd character
EX: asdf asdf asdf asdf
prints out as: a s a s
I have the initial array setup and working, the for loops below are meant to cut the string off at a space in the input and copy it to a new string, but it is not working correctly. I am new to C, and to this site. Any help is greatly appreciated.
#include <stdio.h>
#include <string.h>
int main(){
char a[50];
char b[50];
char c[50];
char d[50];
char e[50];
char f[50];
int i;
printf("enter a string (Ex: asdf asdf asdf... Must have atleast 2 arguments but no more than six): ");
scanf("%s", a);
printf("%c", a);
for (i = 0; i != 50; i++){
if(a[i]==' '){
char strncpy(b, &a[i], i+2);
printf("\n%c ",a[1]);
printf("%c ",b[0]);
}
}
for (i = 0; i != 50; i++){
if(b[i]==' '){
char strncpy(c, &b[i], i+2);
printf("%c ",c[1]);
}
}
for (i = 0; i != 50; i++){
if(c[i]==' '){
char strncpy(d, &c[i], i+2);
printf("%c ",d[0]);
}
}
for (i = 0; i != 50; i++){
if(d[i]==' '){
char strncpy(e, &d[i], i+2);
printf("%c ",e[1]);
}
}
for (i = 0; i != 50; i++){
if(e[i]==' '){
char strncpy(f, &e[i], i+2);
printf("%c ",f[0]);
}
}
return 0;
}
You don't need to copy your strings out of anywhere... Coming from the command line you'll have them sitting in argv:
int main( int argc, char **argv )
{
}
Where argc is the total number of arguments plus 1 (the first is the name that invoked your program), and argv is an array of pointers to each argument string. These have already been tokenised from the command-line.
So first you wanna test you have enough arguments. I like to explicitly make a new variable to remove the off-by-one confusion from comparisons:
int nparams = argc - 1;
if( nparams < 2 || nparams > 6 ) {
printf( "Wrong number of arguments\n" );
return -1;
}
Then you loop over your arguments. The first will be in position 1 of the array... From your example, it seems that you print the first character of the first argument, and the second character of the next, then continue alternating. That's a modulo operation. I have a variable which that chooses which character to print.
int i, which;
for( i = 1; i <= nparams; i++ ) {
which = (i-1) % 2;
printf( "%c\n", argv[i][which] );
}
This does assume that every second argument is at least two characters long. No error checking. If you need error checking, you need to make sure that the character you're printing is not the string-terminator (value 0). In the case of the second character, you also need to check the value before it is not 0. I don't know if it's possible to specify an argument that is a string of zero length. Perhaps a reader who does know can comment.
Well, I may as well put it in... So your loop would look a little like this:
if( argv[i][0] == 0 || argv[i][which] == 0 ) {
printf( "\n" );
} else {
printf( "%c\n", argv[i][which] );
}

Resources