using array to tally votes - c

So I'm working on this program where I need to use arrays, to record the sums of votes for a user inputed number of id's where they will vote for an option a,b,c or d. at the end I will print the sum with the highest votes and declare them the winner. This being said, it's understood that no one may vote more than once. This is where my problem is occurring, I'm trying to set the array for id's(voter_id) to have every value in the area be false until the user specifies his id and then votes, where the value should then be 0, at the id spot in the array.
additionally My program is not printing the printf for successfully voting for a candidate. printf("Successfully voted for %c)
#include <stdio.h>
int main(){
int id;
int a_size;
char ch;
int sum[4];
int i;
int max;
int voter_id[a_size];
sum[0]=0;
sum[1]=0;
sum[2]=0;
sum[3]=0;
voter_id[a_size]=1;
//scan for the array size
scanf("%d", &a_size);
//need to loop and scan for characters while incrementing up the array size until we reach the final array slot
while(id>0 && id!=-1){
printf("What is your id?\n");
scanf("%d", &id);
for (i=0;i<a_size;i++){
voter_id[a_size]=1;
printf("You have already voted. You cannot vote again.");
continue;
}
printf("Welcome %d, which vote would you like to place?\n", id);
scanf("%c\n", &ch);
if (ch== 'A' || ch=='a'){
printf("You have successfully voted for A\n");
sum[0]++;
}
if (ch== 'B' || ch=='b'){
printf("You have successfully voted for B\n");
sum[1]++;
}
if (ch== 'C' || ch=='c'){
printf("You have successfully voted for C\n");
sum[2]++;
}
if (ch== 'D' || ch== 'd'){
printf("You have successfully voted for D\n");
sum[3]++;
}
}
max=1;
for(i=0;i<4;i++){
if (sum[i]>max){
max=sum[i];
}
'A'== sum[0];
'B'== sum[1];
'C'== sum[2];
'D'== sum[3];
printf("%c wins with %d votes", &sum[i], &max);
}
return 0;
}

First of all, take the following as advice and spend the required time doing it, it will reward you later
Format your code so it looks beautiful
believe it or not, this can make you a better programmer.
This in a loop causes problems
scanf("%c\n", &ch);
because you input the '\n' when you press enter, and then the scanf() will consume it on the iteration right after the one where you input your data, you need to explicitly ignore white space characters for the "%c" specifier, like this
scanf(" %c\n", &ch);
This comparison 'D'== sum[3]; does absolutely nothing, I suppose that you tried to assign to the character constant and found this as a workaround, which means that you don't understand what the == operator is for, it's for comparison.
This is also wrong
printf("%c wins with %d votes", &sum[i], &max);
because you are passing the address of the ith element in the sum array, and then you pass the address of max which is also wrong.
This means that you don't know why you use the & address of operator in scanf(), there you need to pass the address of the variable to modify it inside scanf() but in the case of printf() what you need to pass is the value.
If you want to check who won, then
int index;
max = sum[0];
index = 0;
for (i = 1 ; i < 4 ; ++i)
{
if (max < sum[i])
{
index = i;
max = sum[i];
}
}
printf("%c wins with %d votes", index + 'A', max);
in this particular case this will work because 'B' == 'A' + 1 and 'C' == 'A' + 2 and so on.

Related

C program does not recognize my input for 'max'

Hi I keep trying to figuure this out but my input keeps getting ignored, thanks in advance
#include <stdio.h>
#include <stdlib.h>
int main(){
float a, b, a0, b0,i;
char ans;
printf("Fibonacci search method\n\nEnter the function:\n");
printf("\nEnter the intervals over which the Fibonacci method must be applied:\n");
for (i = 1; i <= 1; i++) {
printf("a0 = ", i);
scanf("%f", & a);
printf("bo = ", i);
scanf("%f", & b);
}
printf("Narrow down on either a maximiser or a minimiser (max/min): \n", ans);
scanf(" %c", &ans);
while(ans == 'max'){
printf("maximum selected");
}
printf("minimum selected");
return 0;
}
First of all, you're comparing a single char to a whole string, so you need to modify your ans variable declaration to make it a string, like:
char ans[4]
Keep in mind, this will have a maximum size of 3. If you need to store a bigger string, you'll need to modify this.
Then, after doing this, using a while to do that comparison isn't correct. It's better to implement an if-else. And, inside that, the comparison you're doing is wrong. You need to compare strings, not chars, so you need to use strcmp() function, like:
strcmp(ans,"max") == 0
If this function returns a 0, it means both strings are equal.
Another thing to comment is that you will need to modify your scanf to scan a string, not a char, the new one will be scanf("%3s", &ans);.
And let me tell you one more thing. The for you're using has no sense. You're using a for with parameters i = 1; i <= 1; i++. That means i will start the buckle fulfilling the conditions to break it, so it will only be executed once. In other words, the code inside that for will be executed just once, no matter if it's inside or outside the for.
Anyway, and to sum up, here's your new code:
int main(){
float a, b, a0, b0,i;
char ans[4];
printf("Fibonacci search method\n\nEnter the function:\n");
printf("\nEnter the intervals over which the Fibonacci method must be applied:\n");
for (i = 1; i <= 1; i++) {
printf("a0 = ", i);
scanf("%f", & a);
printf("bo = ", i);
scanf("%f", & b);
}
printf("Narrow down on either a maximiser or a minimiser (max/min): \n", ans);
scanf("%3s", &ans);
if(strcmp(ans,"max") == 0)
printf("maximum selected");
else
printf("minimum selected");
return 0;
}

How can I end a loop once each row and column in a 3x3 tic tac toe board is filled with X's and O's?

So I ask the user to enter X's and O's after the tic tac toe board is completely filled with X's and O's I want the program to end and not continue asking to input values into the board after they already been filled. So I made an integer variable count and set it to 0. After each time both players get asked to enter an either X or O, I want it to increment each round and once count is equal to 10 I want the entire it to break out of the do while loop and end the function. But this seems to not work and keeps asking the user to enter X's and O's. Any suggestions would be helpful, thanks.
void CreateBoard(int m, int n, char board[][n])
{
int i, j, position;
int count = 0;
do {
SCAN:
printf("Enter the number of the cell you want to insert X or O or enter -1 to exit: \n");
scanf("%d", &position);
if(position < 0){
break;
}
if(position > 9){
goto SCAN;
}
printf("Type X or O: \n");
switch(position)
{
case 1: scanf(" %c", &board[0][0]); break;
case 2: scanf(" %c", &board[0][1]); break;
case 3: scanf(" %c", &board[0][2]); break;
case 4: scanf(" %c", &board[1][0]); break;
case 5: scanf(" %c", &board[1][1]); break;
case 6: scanf(" %c", &board[1][2]); break;
case 7: scanf(" %c", &board[2][0]); break;
case 8: scanf(" %c", &board[2][1]); break;
case 9: scanf(" %c", &board[2][2]); break;
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
printf("%c ", board[i][j]);
if (j != 2)
printf(" | ");
}
if (i != 2)
printf("\n------------");
printf("\n");
}
count++;
if(count == 10){
break;
}
}while(position != -1);
}
You have an off-by-one problem.
Let’s deskcheck it:
When the do block starts, count is 0. At the end of the block, it’s 1. Is 1 == 10? Nope. Next.
count is 1. At the end, it’s 2. Is 2 == 10? Nope. Next.
count is 2. At the end, it’s 3. Is 3 == 10? Nope. Next.
etc. until:
count is 9. At the end, it’s 10. Is 10 == 10? Yes. Out.
Let’s count how many times you’re inside the block: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. It’s 10.
So, 10 is one too many. You know the fix.
The answer from adeishs contains the solution to your problem. I just wanted to, if I may, make a few observations that may be helpful.
Use of goto
First is the use of the goto keyword. It is generally considered bad practice to use it on a loop in the way that you have. You would be better off not using it, and using another conditional structure. For example (see here),
// See it in action here https://ideone.com/xM15y8
do
{
printf("Enter the number of the cell y....");
scanf("%d", &position);
const bool input_is_valid = (position == -1) || ((position > 0) && (position < 10));
if (input_is_valid)
break;
printf("\nInput invalid, try again\n");
} while(true);
I have added a check for the input of a zero as this is also an invalid input to your program, as far as I can see.
Use of scanf()
There is a further improvement you could make too. There is a problem with scanf()... the standard says this:
...the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result. If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behaviour is undefined...
So if a user were to type something like 8589934592, although they'd clearly be rather silly to, the is no telling what the variable position may hold as the value entered cannot be represented by an int because it is too large. A safer way might be to use fgets() to read stdin into a small buffer and then use strtol() to parse the input.
Board Size Is Restricted
One other limitation of the function CreateBoard() is that is accepts a board of any dimension, but the function only allows positions 1 - 9 to be input. The switch statement can't do anything more than this. You could deal with this in two ways.
The row index into your board is integer division of zero_indexed_position/num_cols. This translates to (position - 1) / n.
The column index is the remainder of the above - (position - 1) % n.
So we could write, intead of the switch (tested here ),
const int row = (position - 1) / n;
const int col = (position - 1) % n;
scanf(" %c", &board[row][col]);
The other way would be to index the board using *((int *)board + (position -1)), taking advantage of how the array is laid out in memory.

Getting undesired result by using while loop to find the sum of n natural numbers

I am attaching the code for the same.Its working fine.But once i enter a number less than the previous one it stops giving desired output.Any help/suggestion shall be greatly appreciated.
int i=1;
int j=0;
int n;
char ch;
while(ch!='n')
{
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
while(i<=n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%s",&ch);
}
return 0;
In your outer while loop, you're never resetting the value of the variable i back to 1, or j back to 0. That is why subsequent loops will produce an incorrect sum.
There are a smattering of bugs in this code, including:
Comparison to uninitialized value of of ch in the initial while expression.
Failing to reset i and j for each outer-loop iteration
Failing to test for data-read success in either scanf call to ensure proper input.
The continuation scanf("%s", &ch) is simply wrong for a single character with skipped whitespace (which you must do to avoid reading the newline after your list integer input). Unless EOF or an error state is reached, what you have now is guaranteed to invoke undefined behavior, as a string-read of at least one character requires at least two for storage (the character, and a subsequent terminator).
Addressing all of those:
#include <stdio.h>
int main()
{
char ch;
do
{
int n;
printf("Enter the number upto which you want the sum of \n \n");
if (scanf("%d", &n) != 1) // See (3)
break;
int j = 0; // See (2)
for (int i = 1; i <= n; ++i) // See (2)
j += i;
printf("%d \n", j);
printf("Do it with another number? Y/N \n \n");
if (scanf(" %c", &ch) != 1) // See (3) and (4)
break;
} while (ch != 'n' && ch != 'N'); // See (1)
return 0;
}
Everything here is self-explanatory when referred to the previous bug punch list, save for maybe the format string for reading the single character. You mentioned in comments that you tried %c but it skipped to another loop iteration. That's because you didn't have the leading whitespace " %c" that tells scanf to skip white space before extracting the next argument. With that, it should work as desired.
You need to reset i and j for every n.
i = 1;j=0;
while(i<=n)
{
Also your format specifer is wrong. For char, it should be %c and not %s
scanf("%c",&ch);
The simplest solution is to set i to 0 at the outer while:
int i=1;
int j=0;
int n;
char ch;
while(ch!='n')
{
i = 0;
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
while(i<n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%s",&ch);
}
return 0;
Note that I have changed <= to < for your inner while, since you do not want to increment the value if the same n is inputted one after the other.
#include<stdio.h>
int main(){
int n;
char ch;
while(ch!='n')
{
printf("Enter the number upto which you want the sum of \n \n");
scanf("%d",&n);
int i=1;//it should be 1 in every loop of the number
int j=0;//the sum should also be initialized to zero to erase the previous value
while(i<=n)
{
j=j+i;
i++;
}
printf("%d \n",j);
printf("Do it with another number? Y/N \n \n");
scanf("%c",&ch);//this is a char not a string
}
return 0;
}
Due to the i is not initializing to 1 when the loop is coming for the second time there it is not going inside the loop and printing the previous value .

How i cannot ignore 0(zero) as a grade?

int main(){
char students_number[30], students_grade[30];
char *number, *value;
int flag=0, students, i, grade, a=0, b=0, c=0, d=0, f=0;
float sum=0;
while(flag==0) // This while loop exist just because to run program until the number of students will be given correct..
{
printf("Please enter the number of students (It must be between 1-100): ");
scanf("%s",&students_number); // This scanf gets the number of students as an array instead of integer because the number which was given needs to be checked..
students = strtol(students_number, &number, 10); // strtol is a function of stdlib.h and checks the variable is whether int or not for this program..
if(students<=100 && students>0)
{
for(i=1;i<=students;i++)
{
printf("Please enter %d. student's grade (in integer form):",i);
scanf("%s",&students_grade);// This scanf gets the number of students as an array instead of integer because the number which was given needs to be checked..
grade = strtol(students_grade, &value, 10); // This line checks the grade which was given is integer or not by using strtol which is in the stdlib.h..
if(grade<0 || grade>100 || grade=='\0')
{
printf("The grade of the student was given incorrect!\n");
i--; // To make the for loop which is on the 25th line work again until the grade will be given correct..
}
else
{
if(grade<=50 && grade>=0) // This if and else if commands work for to count how many f,d,c,b and a are exist..
f++;
else if(grade<=60 && grade>=51)
d++;
else if(grade<=73 && grade>=61)
c++;
else if(grade<=85 && grade>=74)
b++;
else if(grade<=100 && grade>=86)
a++;
sum += grade;
}
}
sum /= students; // This command divides the sum of the grades to number of the students to get the average results in the class..
printf("\nThe average result of the class is %.2f..\n",sum);
printf("\nThe letter form of the all results are:\nNumber of F: %d\nNumber of D: %d\nNumber of C: %d\nNumber of B: %d\nNumber of A: %d\n",f,d,c,b,a);
flag = 1; // As it was mentioned before, this commands exist to break the while loop because the program was done successfully..
}
else // This if command controls the number of students wheter was given right or not..
{
printf("Please enter a proper number of students.\n");
flag = 0;
}
}
return 0;
}
Hello, this is my first question. I had to create a program which calculates the average of the results. But when i enter 0(zero) as a grade then it doesn't allow it just because i tried to exclude the every types except int type.
How can i make this correct?
You can use scanf to read a number and check that scanf done correctly its work:
from man scanf:
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
So you can check that you've read an integer with scanf, without writing if (value == '\0'), which prevents you to read 0 grades...
for(i=1;i<=students;i++)
{
int ok;
printf("Please enter %d. student's grade (in integer form):",i);
/* read line from input. Why using fgets instead of scanf directly? See http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html*/
if (NULL == fgets(students_grade, sizeof students_grade, stdin))
{
perror("fgets");
exit(1);
}
/* **try** to parse what have been read */
ok = sscanf(students_grade, "%d", &value);
/* check that scanf has done its work */
if (1 != ok)
{
printf("The grade of the student was given incorrect!\n");
i--; // To make the for loop which is on the 25th line work again until the grade will be given correct..
}
else
{
if(grade<=50 && grade>=0) // This if and else if commands work for to count how many f,d,c,b and a are exist..
f++;
/* ... */
}
I also advice you to read this article: http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html.

Scanning line of input with char and num

So I'm doing this problem where I need to calculate the average using pointers and without using strings. The user will input a letter and then a space followed by a number(an integer), the letter indicating if the number is positive(p) or negative(n) or if the user is done input-ing numbers(e).
I know I need a loop to continually read in number and add or subtract them from the sum until the letter "e" is input.
program should have and use the following function
// Precondition: value will be a pointer to where the input value is to be stored.
// Postcondition: returns true if a number was read, or false if
// it was the end of the list. The int pointed to by value will be
// set to the number input by this function, made negative or
// positive depending on the character before it. int read_number(int* value);
A sample input being p 20 p 20 p 10 p 10 e
output: 15
My problem as of now is my loop is only reading for two cycles of input, and even then it isn't printing the average. Also I'm supposed to use a pointer but given the directions i'm still not sure what the context is, I'm not seeing where a pointer is useful.
#include <stdio.h>
//precondition: value will be a pointer to where the input value is to be stored.
int main(){
int sum;
int num;
int counter;
float avg;
char let;
scanf("%c %d", &let, &num);
for (counter=0;let == 'n' || let == 'p'; counter++){
scanf("%c %d", &let, &num);
if ( let == 'n'){
sum-=num;
}
if (let == 'p'){
sum+=num;
}
if ( let == 'e'){
avg=sum/counter;
printf("%f", &avg);
}
}
return 0;
}
Your input is:p 20 p 20 p 10 p
10 e.
The scanf before the loop scans 'p' and then skips the space and then scans 20. The next scanf in the loop reads the space as it is also a character and the %d fails to scan an int and the stops scanning. See the problem?
To fix it, change
scanf("%c %d", &let, &num);
To
scanf(" %c %d", &let, &num);//Note the space before %c
The space before %c gobbles up whitespace characters(if any) like newlines, spaces etc until the first non whitespace character.
Other problems include not initializing sum to 0 and using &avg instead of avg in the printf below
printf("%f", &avg);

Resources