How to find matching values in two arrays? - c

I need to get the user to input 6 numbers and I store those in an array called winningNum[]. Then I have to read in a file that has a bunch of users firstName lastName and the numbers they have guessed. I need to compare these two arrays and only print out the first and last name of the users from the file that got a minimum of three numbers matched.
This is the struct of for the input file users
typedef struct
{
char firstName [20];
char lastName [20];
int numbers[6];
}KBLottoPlayer;
Getting the winning numbers from the user
int getNum()
{
int winningNum[6];
int i;
printf("Please enter the six nunbers between 1-53:\n");
scanf("%d %d %d %d %d %d", &winningNum[0], &winningNum[1],
&winningNum[2] ,&winningNum[3], &winningNum[4], &winningNum[5] );
}
This is where I am reading in the file and putting it into the struct array
KBLottoPlayer* readArray()
{
int i,size;
FILE *in = fopen("KnightsBall.in","r");
fscanf(in,"%d",&size);
KBLottoPlayer* temp;
temp =(KBLottoPlayer*)malloc(sizeof(KBLottoPlayer)*size);
if((in = fopen("KnightsBall.in", "r")) != NULL )
{
char buffer[100];
fgets(buffer, 5, in);
for(i=0;i<size;i++)
{
fscanf(in," %s %s ", temp[i].firstName, temp[i].lastName);
fscanf(in,"%d %d %d %d %d %d ", &temp[i].numbers[0],
&temp[i].numbers[1], &temp[i].numbers[2], &temp[i].numbers[3],
&temp[i].numbers[4], &temp[i].numbers[5]);
}
}
else
{
printf("File is Not Exist.\n");
}
return temp;
}
I essentially need to only store the first and last name of the users that got 3 4 5 6 of the winning numbers correct.

I will admit that you only need hints to go past a problem.
Unrelated, but you never test your input functions. Beware a single incorrect line will give undefined results and you will not even know where the problem is. Remember: never trust what comes from the outside.
Back to your problem. A simple way is to use 2 nested loops, one on the winning numbers and one on the guessed ones just counting the matches: if the total number of matches is at least 3, you keep the record, else you reject it. You can even do that when reading the file (here in pseudo-code):
int recnum = 0; // next record to store
for (int i=0; i<size; i++) { // loop over the input file
read the line into temp[recnum]
int count = 0; // number of correct guesses
for (int j=0; j<6; j++) { // loop over the winning numbers
for (int k=0; k<6; k++) { // loop over the guessed numbers
if winning[j] == guessed[k] {
count++;
}
}
}
if (count >= 3) recnum++; // only keep if at least 3 correct guesses
}

Related

Why the output file isn't the same as the input of the variable?

I create it a program that asks for raw and columns after that asks you to put numbers to the dimensional array. This arrays inputs to a file. When i open the file i can't see the array.
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
int main () {
FILE *fp;
int n,m;
int i,j;
float b;
char filename[100];
int getfloat(float *);
printf("Number of rows\n");
scanf("%d",&n);
printf("Number of colums\n");
scanf("%d",&m);
float s[n][m];
for (i=1;i<=n;i++)
{
for (j=1;j<=m;++j)
{
printf("Insert number %d",i);
printf(",%d\n", j);
scanf("%f",&b);
s[i][j]=b;
}
}
printf("Enter file name \n");
scanf("%s", filename);
// ****print file****
fp=fopen(filename,"w+");
if(fp!=NULL)
{
fputs(s,fp);
fprintf("%c",s);
}
fclose(fp);
return 0;
the only thing i see is this
If you want a list of numbers, probably in some kind of grid in the file, then at the minimum you want a loop such as the following:
for (int i=0; i<n; ++i)
{
for (int j=0; j<m; ++j)
{
fprintf(fp, "%f ", s[i][j]);
}
fprintf(fp, "\n");
}
See fprintf for documentation on the format specifiers; you'll probably want to tweak that to get better-looking values.
Also, again, note that arrays start from 0. Your initial read loop skips the very first element, and writes past the end of the actual array.
fprintf("%c", s); and fputs does not print out the contents of the array, it prints out the location stored in the array's pointer and tries to interpret it as a char. What you would need to print out the proper values is to loop through each value and use fprintf with each float value, using s[i][j] similar to how you initialized it.
The way you initialized the array is also off, as arrays begin at 0, not 1. Currently your for loop does not ever access s[0][0] or s[1][0] and so on. Your for loops should have i initialized to 0, and have the condition be i < n instead of i<=n.

Read a line from a text and enter as input until EOF

I have written a program that when executed, prompts the user to enter an integer for five times. It returns two arrays,one containing the odd numbers and the other one, the odd ones.
This is my code:
#include <stdio.h>
#define SIZE 5
int array[SIZE];
int odd[SIZE];
int even[SIZE];
int index_odd=0;
int index_even=0;
int main()
{
for(int i=0; i < SIZE; i++)
{
scanf("%d", &array[i]);
if(array[i]%2==0)
{
odd[index_odd]=array[i];
index_odd++;
}
else
{
even[index_even]=array[i];
index_even++;
}
}
printf("\nOdd numbers: \n");
for(int i=0; i < SIZE; i++)
printf("%d ", odd[i]);
printf("\nEven numbers: \n");
for(int i=0; i < SIZE; i++)
printf("%d ", even[i]);
printf("\n");
return 0;
}
Is it possible for the program to, instead of reading from a terminal, to read from a text file, as in a turn-by-turn based game:
read a line as input
assign input(value) to the right array
read the next line
assign input(value) to the right array
and so on until EOF.
The actual thing I am trying to build is a CARDIAC COMPUTER simulator, and the way it works is, it takes a series of numbers, assigns them to the right indexes of an array and then depending on what values they hold, performs operations within that array and outputs the result.
What do I need to implement in my code in order to:
read line from a text file
save it to the assigned index/array
read next line
save it to the assigned index/array

Extreme sum values calculated inside a structure

While I was learning to code in C about structure and pointers, I tried to make a program that calculate grades of students.
I thought it would work from my previous experiences for such calculation without pointers and structure. But with those, it gave me wild results in the program.
#include <stdio.h>
#include <string.h>
/*
The program will scan year, name, score of three different subjects,
and calculate the sum and the average.
Three different people (using array) will be taken into account.
*/
struct grade {
int year;
char name[20];
int score[3];
int total;
float avg;
};
void main() {
struct grade p[3];
char str = 'c';
char *pstr = NULL;
int i, j;
pstr = &str;
for (j = 0; j < 3; j++) {
printf("Year of Admission: ");
scanf("%d", &p[j].year);
printf("Name of the Student: ");
scanf("%s", pstr);
strcpy(p[j].name, pstr);
for (i = 0; i < 3; i++) {
printf("The score for Subject %d: ", i + 1);
scanf("%d", &p[j].score[i]);
p[j].total += p[j].score[i];
}
p[j].avg = p[j].total / 3.0;
}
for (j = 0; j < 3; j++) {
printf("%s's\n", p[j].name);
printf("Total score: %d\n", p[j].total);
printf("Average: %.2f\n", p[j].avg);
}
}
I could have written each of three different subjects as one variable but for an extra "challenge", I made an array inside the structure.
int score[3];
However, the program only prints out extremely small number -89541694... for both totals and averages.
I assume that this particular line inside a for-loop is a problem.
scanf("%d", &p[j].score[i]);
But I could not figure out why. I am really new to pointers and still learning them.
I hope for your generous teaching and explanations.
Thank you in advance.
Local variables are not initialized with 0, so you just need to zero it before calculating total:
p[j].total = 0;
before
for (i = 0; i < 3; i++) {
printf("The score for Subject %d: ", i + 1);
scanf("%d", &p[j].score[i]);
p[j].total += p[j].score[i];
}
The variable pstr points to a single char. A string in C needs to be at least two characters for a single-character string: The actual character, and the null terminator.
When you use e.g. scanf to read a string, the function will write at least two bytes to the memory pointed to by pstr. But since it only points to a single byte you will write out of bounds and that leads to undefined behavior.
If you want to be able to read more than a single character you need to have more space allocated for the string. And you need to limit scanf so it will not write out of bounds.
For example
char pstr[40]; // Allows for strings up to 39 character, plus terminator
// ...
scanf("%39s", pstr); // Read at most 39 characters from standard input, and write to pstr
Another problem is that local variables are not automatically initialized, their values will be indeterminate.
That means the contents of the array p is unknown and seemingly random.
When you do
p[j].total += p[j].score[i];
you use the seemingly random value of p[j].total to calculate another seemingly random number.
To initialize all structures and all their members to "zero" in the array, do e.g.
struct grad p[3] = { 0 };
Instead of making pstr a pointer you might wanted to do somehting like this
char pstr[30];
And accordingly you will scanf the string using scanf("%29s",pstr); and check it's return value.
To describe the problem a bit - you had a pointer pointing to a char which is not capable of holding an input characters and the corresponding \0 (nul terminating character). As a result this gives rise to undefined behavior. And then using it in strcpy is also an illegal code. (Undefined behavior).
Here the solution I gave simply declared an array of 30 characters and we limited the string input using scanf upto 29 characters because we need to store the terminating null.
Showing you atleast a bit of code to make you understand how to write these codes:-
if( scanf("%29s",pstr)!= 1){
fprintf(stderrm"Error in input");
exit(EXIT_FAILURE);
}
Another problem is initialize the variables - here you used p[j].total += p[j].score[i]; What is the value of p[j].total initially. It contains garbage value. In the loop make p[j].total = 0; first. That will give you the correct result.
Note: The wild results are the garbage value resulted from addition of some garbage value with p[j].score[i].
Also note that without making the changes that I said if you only change the initialization thing then also code is not guranteed to work. undefined behavior is undefined behavior - cases may arise which will simply crash the program making you wonder where you went wrong.
Illustration code may help you:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
The program will scan year, name, score of three different subjects,
and calculate the sum and the average.
Three different people (using array) will be taken into account.
*/
struct grade {
int year;
char name[20];
int score[3];
int total;
float avg;
};
int main(void) {
struct grade p[3];
char pstr[20];
int i, j;
for (j = 0; j < 3; j++) {
printf("Year of Admission: ");
if(scanf("%d", &p[j].year)!=1){
fprintf(stderr, "%s\n", "Error in input");
exit(EXIT_FAILURE);
}
printf("Name of the Student: ");
if(scanf("%19s", pstr)!=1){
fprintf(stderr, "%s\n", "Error in input");
exit(EXIT_FAILURE);
}
strcpy(p[j].name, pstr);
p[j].total = 0;
for (i = 0; i < 3; i++) {
printf("The score for Subject %d: ", i + 1);
if(scanf("%d", &p[j].score[i])!=1){
fprintf(stderr, "%s\n", "Error in input");
exit(EXIT_FAILURE);
}
if(p[j].score < 0){
fprintf(stderr, "%s\n", "Error in input");
exit(EXIT_FAILURE);
}
p[j].total += p[j].score[i];
}
p[j].avg = p[j].total / 3.0;
}
for (j = 0; j < 3; j++) {
printf("%s's\n", p[j].name);
printf("Total score: %d\n", p[j].total);
printf("Average: %.2f\n", p[j].avg);
}
return 0;
}
In fact instead of using the pstr just input the names directly in the structure variable instance itself. No need to use a temporary variable.

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.

Reading a file and converting the input into two arrays

I want to read a file containing numbers in two columns.
1 2
3 4
5 6
7 8
I want to place the numbers in the first column into one array, and the ones in the second column into another array. Both of these arrays will always have the same amount of elements. The maximum number of elements permitted in this program is 100.
Here's what I have so far. This just reads in the elements as regular int and prints them out.
while (!feof (filereader))
{
printf ("%d %d\n",col_one,col_two);
fscanf (filereader, "%d %d", &col_one, &col_two);
}
So how do I place the numbers in the first column from the file into one array and the numbers in the second column into an array?
int array1[100];
int array2[100];
int i, size = 0;
while (size<100 && fscanf (filereader, " %d %d", &array1[size], &array2[size])==2)
{
size++;
}
for (i=0; i<size; i++) {
printf("array1[%d] = %d, array2[%d] = %d\n",
i, array1[i], i, array2[i]);
}
add space at the beginning of the format specifier of scanf " %d %d" this will avoid the problem of newlines in your file
Since you've got a maximum size, it's pretty easy. Just define the arrays like so:
int firstArray[100];
int secondArray[100];
int size = 0;
Then do your loop, incrementing the index for each line:
while (!feof (filereader))
{
fscanf (filereader, "%d %d", &col_one, &col_two);
firstArray[size] = col_one;
secondArray[size] = col_two;
size++;
}
Maybe also think about making sure size < 100 in case the file is too long.

Resources