I'm writing a program for my computing class that scores a tennis match. The program takes inputs for teams as 'A' and 'B' for teams, and 'S' to print the score out. It works fine until it gets to the deuce function.
The problem I'm having is that multiple inputs at one time break the program. So once the deuce has started, input of: 'A, Enter, B, Enter, B, Enter', works fine, but 'A, B, B, Enter' breaks it. Unfortunately the auto-marker at uni just shoves long strings of characters at it. This also makes it hard to test because I can't see what is happening at each stage of input.
I've got a while loop trying to consume some of the extra characters I was getting, but it's still not quite right. I've had problems before where an input of 'A' will output 'AA', I think it's something similar.
I'm just learning so I'm sure I just misunderstand how to use the getchar() function. Also I know there are parts of my code that could be simpler, but it's due really soon and I haven't had, and probably won't have, time to optimise it properly.
Thanks for any help!!!
EDIT: Sorry, reading back on my question I can see I worded it quite badly. It doesn't ever 'break' and -Wall gives no errors or warnings, it just gives the wrong output. For example, the input 'ABB' should go like this:
A: The program thinks that A has the advantage.
B: The program thinks that B has equalised, so the deuce restarts.
B: B should now have the advantage.
(If I hit 'Enter' after every input, the above output is exactly what happens.)
But if 'ABB' is typed in all at once, and then 'Enter' is pressed it exits the deuce function entirely, thinking that 'B' has won the deuce and keeps going with the normal tennis match. So I think what is happening is that an extra 'B' is being passed through the while loop.
void deuce ( int data_array[], int set_tally[], int team_select ){
int A_deuce_points = 0;
int B_deuce_points = 0;
int server = data_array[data_array[8]];
int ch = 0;
int winner = 0;
while ( A_deuce_points < 2 && B_deuce_points < 2){ // needs to be &&
ch = getchar();
printf("ch = %d\n", ch);
while ( ch == 10 || ch == -1 || ch == '\n' ){
ch = getchar();
}
if ( ch == 'A' ){
A_deuce_points++;
}
else if (ch == 'B'){
B_deuce_points++;
}
else if (ch == 'S' ){
printf("Team %c to serve:\n", server);
if ( server == 'A' ){
// Print sets
winner = server;
print_completed_sets( set_tally, winner );
// Print games
printf("%d-%d\n", data_array[4], data_array[5]);
if(A_deuce_points == B_deuce_points ){
printf("Deuce\n");
A_deuce_points = 0;
B_deuce_points = 0;
}
if(A_deuce_points - B_deuce_points == 1 ){
printf("Advantage Server\n");
}
if(B_deuce_points - A_deuce_points == 1 ){
printf("Advantage Receiver\n");
}
}
else if ( server == 'B' ){
// Print sets
winner = server;
print_completed_sets( set_tally, winner );
// Print games
printf("%d-%d\n", data_array[5], data_array[4]);
if(A_deuce_points == B_deuce_points ){
printf("Deuce\n");
A_deuce_points = 0;
B_deuce_points = 0;
}
if(B_deuce_points - A_deuce_points == 1 ){
printf("Advantage Server\n");
}
if(A_deuce_points - B_deuce_points == 1 ){
printf("Advantage Receiver\n");
}
}
}
}// end while loop
if ( A_deuce_points == 2 ){
data_array[4]++;
}
else if ( B_deuce_points == 2 ){
data_array[5]++;
}
data_array[2] = 0;
data_array[3] = 0;
A_deuce_points = 0;
B_deuce_points = 0;
change_serve( data_array);
}
Related
I need to write a program to count how many vowels (‘a’, ‘e’, ‘i’, ‘o’, ‘u’) in a list of input words. My program reads the words one by one and prints the number of vowels occurring in each word. Each word consists of only alphabets in mixed cases. The program repeats this process until hitting the word “exit” (case-insensitive). In this case, terminate the program after printing the number of vowels in “exit”. After termination, the program shall ignore remaining inputs, if any.
Input: Multiple words spanning across lines.
Each word shall consists of no more than 50 characters.
The words are separated by white spaces.
Output: The number of vowels in each of the input word, separated by newline.
That is, one number on a line.
Example expected input output
Input:
I go to school by BUS
Exit
Output:
1
1
1
2
0
1
2
Another Input:
I
went
apple
school
by
BUS
Exit
Output:
1
1
2
2
0
1
2
I am having problem with "Time limit exceed" and i do appreciate any feedback to my program
when i input:
I go to school by BUS
i got a notification Time limit exceed and an output :
1
1
1
2
0
1
#include <stdio.h>
#include <string.h>
int main(void)
{
char s1[51], ex[5];
int N, i, v, newline=1;
while(newline){
fgets( s1, 51, stdin);
if((s1[0]=='e' || s1[0]=='E')&&(s1[1]=='x' || s1[1]=='X')&&(s1[2]=='i' || s1[2]=='I')&&(s1[3]=='t' || s1[3]=='T')&&(s1[4]=='\0' || s1[4]==' ')){
printf("2\n"); // to check whether the input is Exit
newline=0;
}
else{
N=strlen(s1);
for(i=0;i<N;i++){
if(s1[i]=='a' || s1[i]=='o' || s1[i]=='e' || s1[i]=='i' || s1[i]=='u' || s1[i]=='A' || s1[i]=='O' || s1[i]=='E' || s1[i]=='I' || s1[i]=='U'){
v++; // to calculate the number of vowels
}
if(s1[i+1]==' '){ // if next entry is spacebar, print the number of vowels in the current word and add i so that next loop will start on new word
printf("%d\n", v);
v=0;
i++;
}
else if(s1[i+1]=='\n'){ // if next entry is new line, print the number of vowels in the current word, restart the whole program by exiting the for loop
printf("%d\n", v);
v=0;
newline=1;
break;
}
}
}
}
return 0;
}
You should review few things:
When compare char, case-insensitive, is easy to do like that:
char c1, c2;
if ( toupper(c1) == toupper(c1) ) {
do_something();
}
To exit from a loop, I would use break; instead of return;
The whole code would be this:
#include <stdio.h>
#include <ctype.h>
int isVowel(char c);
int isExit(char* c);
int main(void)
{
char s1[51];
int N, i, v = 0;
int noExit = 1;
while( noExit ){
fgets( s1, 51, stdin);
N=strlen(s1);
for(i=0;i<N;i++) {
if ( isExit(&s1[i]) ) {
printf("2\n");
noExit = 0;
break;
}
else{
if( isVowel(s1[i]) ) {
v++;
}
else if( s1[i]==' ' || s1[i]=='\n' ) {
printf("%d\n", v);
v=0;
}
}
}
}
return 0;
}
int isVowel(char c) {
c = toupper(c);
if( c=='A' || c=='E' || c=='I' || c=='O' || c=='U' )
return 1;
else
return 0;
}
int isExit(char* c) {
if ( (toupper(c[0]) == 'E') && (toupper(c[1]) == 'X') &&
(toupper(c[2]) == 'I') && (toupper(c[3]) == 'T') ) {
return 1;
}
else {
return 0;
}
}
You have an infinite loop. newline will never be 0. and the outer while loop will never exit.
So, you need to change the newline=1 in the last else if condition to newline=0.
In addition, the variable v is not initialized, so you are not getting the first answer correctly. You should set v=0 at the beginning before the while loop starts.
Hey guys im trying to write a small program where the user has to put in a number between 1-9, anything else is an error, but I'm having trouble validating the input because if you put 12 it only reads the 1 and it goes in the loop. It has to be done using getchar() this is what have so far:
printf(%s,"please enter a number between 1 - 9);
int c;
c = getchar();
while(c != '\n') {
int count = 1;
count ++;
if ((c >= '0' && c <= '9') || count > 1) {
printf(%s, "Congrats!);
}
else
{
print(%s, "ERROR);
}
}
I'm also having problems validating the char into an int after it goes in. If i put in 5 i get 53.
Try changing count > 1 to count == 1, and initialize it to 0 rather than 1. That way you can keep count of the number of digits you have. Also, note that because you initialize count to 1 and then immediately increment it, count > 1 will always evaluate to true, so if you gave it any char it will always say it's correct.
getchar() will return the next character typed. If you want more than the first character you will need a call getchar() again within the while loop.
//Somewhere to store the result
//initialized with an invalid result value
int digitchar = 0;
//Get the first char
int c = getchar();
while (c != '\n')
{
//Check if we already have a digit
//and that the new char is a digit
if (digitchar == 0 && c >= '1' && c <= '9')
{
digitchar = c;
}
//Get the next char
c = getchar();
}
//Check if we have stored a result
if (digitchar != 0)
{
//Success
}
Note this doesn't handle if a non-digit or newline character is entered. You would need to handle that as an error as well as if more than one digit is entered.
This is not working with 12 because getchar() takes one character per time.The following example is one way to solve it.
printf("please enter a number between 1 - 9");
int c[10], count=1;
//Declare an array because user may insert a bigger number
char number;
//This loop allow the user to enter an input
for(i=0;i<10;i++){
number = getchar();
if (number != ' '){
c[i] = atoi(number);
sum = sum + c[i];
}
else if(number == ' '){
//Terminate the loop when user stop typing
break;
}
else if( sum > 9 || sum < 0){
//Start loop again until user enter valid input
printf("You entered a number out of field try again\n");
continue;
}
}
while(c != '\n') {
count ++;
if ((c >= '0' && c <= '9') || count > 1) {
printf("%d Congrats!",c);
}
else
{
printf(" %d ERROR", c);
}
}
Remember that getchar() returns the ascii value of the char, thus when you pass the value to the function you must subtract char '0' to pass the actual decimal value into the function.
Another point is that you must clear the input buffer. If your user enters wrong input, you have to make sure that there is nothing left on the input buffer before you try to read input again.
Hope this helps.
int main(void) {
int input = 0; // 0 is the sentinel value to close program
printf("\n%s\n", "Enter value between 1-9 .\nEnter [0] to finish.");
do {
input = getchar();
if (((input>= '1') && (input <= '9') || input == '0') && getchar() == '\n') {
if ((input >= '1') && (input <= '9')) {
callYourOwnFuntionAndPassValue(input - '0');
printf("\n%s\n", "Enter value between 1-9 .\nEnter [0] to finish.");
}
}
else {
while (getchar() != '\n') {} // clear input buffer
printf("\n%s\n", "Please enter a valid number");
}
} while (input != END_PROGRAM);
return NO_ERROR; // NO_ERROR = 0
}
I have written the below code and need help understanding why it's not working the way it should. It compiles, however, it isn't running the if-else in my loops. For example, if I were to take out the while loop in my code everything would work fine, however, I want to know how many tries it takes for someone to guess the "magic number" or random number in this case.
#include <stdio.h>
int main()
{
int magicnum = 1234;
int userguess;
int totalguess = 0;
printf("Try to guess a number between 1 and 10000!: ");
scanf("%d", &userguess);
while(totalguess <= 7 && magicnum != userguess);{
if(magicnum == userguess){
printf("Congratulations, You Win!!\n");
if(totalguess = 1){
printf("Wow you did it on your first try!!\n");
}
else(totalguess >= 2); {
printf("Nice one!! It only took you %d tries!\n", totalguess);
}
}
else if(magicnum > userguess){
printf("Too Low try again!!\n");
}
else{
printf("Too High try again!!\n");
}
totalguess++;
}
return 0;
}
I am looking for an output of either someone answering the correct number which is "1234" if they score too high they should see the response of "Too High try again!!", and if they score too low they should see the response of "Too low try again!!. Also, it is supposed to show how many attempts it took them, and if they got it on the first try or not. The max number of attempts a person should be able to do this should be 7.
Problem #1 problem lies in the line
while(totalguess <= 7 && magicnum != userguess);{
Specifically at the semicolon. The above evaluates to the following
// Sit on this line until a condition is met
while(totalguess <= 7 && magicnum != userguess);
// Some block of code which is unrelated to the while loop
{
...
}
The answer is to remove the extraneous semicolon at the end of the while loop:
while(totalguess <= 7 && magicnum != userguess) {
// No semicolon ^
Problem #2 is in the line
if (totalguess = 1){
Where you are actually assigning totalguess to 1. Fix this by changing = (assignment) to == (comparison).
Problem #3 and #4 are in the line
else(totalguess >= 2); {
Not sure how this is even compiling, but you should have an else if rather than an else. And as with the while loop, you have another extraneous semicolon. Remove it.
Lastly, you are only asking for user input once, so the program will loop 7 times without asking for input. Put your scanf inside the main while loop
According to Levi's findings, a solution:
const int magic_num = 1234;
const uint max_num_guess = 7;
uint num_guess = 1 + max_num_guess;
int user_guess;
printf( "Try to guess a number between 1 and 10000!\n" );
for( uint idx = 0; idx < max_num_guess; ++idx )
{
scanf( "%d", &user_guess );
if( magic_num == user_guess ) { num_guess = 1 + idx; idx = max_num_guess; }
else
{
if( magic_num < user_guess ) { printf( "Too High try again!!\n" ); }
else { printf( "Too Low try again!!\n" ); }
}
}
if( num_guess <= max_num_guess )
{
printf( "Congratulations, You Win!!\n" );
if( 1 == num_guess ) { printf( "Wow did it on your first try!!\n" ); }
else { printf( "Nice one!! %d tries!\n", num_guess ); }
}
To #3 it is valid. Consider:
if(false){}
else(printf("Branch!\n"));
{ printf("Done.\n"); }
For example :I want to terminate inputting without using (ctrl+d or pressing any character) as doing this cause the program to execute and the second scanf() does not work.I am not allowed to input number of elements in the array.
for(i=0;a[i]<10000;i++)
{
if(scanf("%d",&a[i])==1)
count++;
}
for(j=0;a[j]<10000;j++)
{
if(scanf("%d",&b[j])==1)
count1++;
}
You can do something like that:
for(i=0;a[i]<10000;i++)
{
// chack that input correct
if((scanf("%d",&a[i])==1)
{
count++;
}
else // if input is incorrect
{
// read first letter
int c = getchar();
if( c == 'q' )
{
break; // stop the loop
}
// clean the input buffer
while( getchar() != '\n' );
}
}
and when you want to stop entering just enter letter q instead of number
If you want to come out of first loop when scanf() reads a character, then you may consider reading integers using getchar(). You may add an extra condition to that function in the link to mark a flag when some particular character is entered.
For example if you want to end the loop when input is X, you can use something like this
int get_num()
{
int num = 0;
char c = getchar_unlocked();
while(!((c>='0' && c<='9') || c == 'X'))
c = getchar_unlocked();
if(c == 'X')
return 10001;
while(c>='0' && c<='9')
{
num = (num<<3) + (num<<1) + c -'0';
c = getchar_unlocked();
}
return num;
}
//------------//
for(i=0;;i++)
{
temp = get_num();
if(temp < 10000)
count++;
else
break;
}
for(j=0;;j++)
{
temp = get_num();
if(temp < 10000)
count1++;
else
break;
}
My task is:
Write a program that reads input up to # and reports the number of times that the sequence ei occurs.
I wrote something that in most of the times works, but there are inputs when it dosent...
Like this input:(suppose to return 1)
sdlksldksdlskd
sdlsklsdks
sldklsdkeisldksdlk
#
number of combination is: 0
This is the code:
int main(void)
{
int index = 0;
int combinationTimes = 0;
int total = 0;
char userInput;
char wordChar[index];
printf("please enter your input:\n");
while ((userInput = getchar()) != '#')
{
if (userInput == '\n')
continue;
wordChar[index] = userInput;
index++;
total++;
}
for (index = 1; index < total; index++)
{
if (wordChar[index] == 'i')
{
if (wordChar[--index] == 'e')
{
combinationTimes++;
++index;
}
}
}
printf("number of combination is: %d", combinationTimes);
return 0;
}
Can you please tell me what am I not getting 1 using this input?
in the book he said to test it with "Receive your eieio award" and it worked...but after i played with it a little i see that not always.
It really doesn't seem necessary to read the file into an array. You just need to keep track of how many times ei is found before you read a # or reach EOF:
#include <stdio.h>
int main(void)
{
int c;
int ei_count = 0;
while ((c = getchar()) != EOF && c != '#')
{
if (c == 'e')
{
int c1 = getchar();
if (c1 == 'i')
ei_count++;
else if (c1 != EOF)
ungetc(c1, stdin);
}
}
printf("ei appeared %d times\n", ei_count);
return(0);
}
Testing (the program is called ei and is built from ei.c):
$ ei < ei.c
ei appeared 0 times
$ sed 1d ei.c | ei
ei appeared 1 times
$ sed 's/#/#/' ei.c | ei
ei appeared 4 times
$
The first one stops at the #include line, the second stops at the # in the comparison, and the third reads the entire file. It also gives the correct output for the sample data.
Analysing the code
Your primary problem is that you do not allocate any space for the array. Change the dimension of the array from index to, say, 4096. That'll be big enough for your testing purposes (but really the program should pay attention to the array and not overflowing it — but then I don't think the array is necessary at all; see the code above).
The next primary problem is that despite its name, getchar() returns an int, not a char. It can return any valid character plus a distinct value, EOF. So it must return a value that's bigger than a char. (One of two things happens if you use char. If char is a signed type, some valid character — often ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS — is also treated as EOF even though it is just a character. If char is an unsigned type, then no input matches EOF. Neither is correct behaviour.)
Fixing that is easy, but your code does not detect EOF. Always handle EOF; the data may be malformatted. That's a simple fix in the code.
A tertiary problem is that the printf() statement does not end with a newline; it should.
Your test condition here is odd:
if (wordChar[--index] == 'e')
{
combinationTimes++;
++index;
}
It's odd to use one pre-increment and one post-increment, but that's just a consistency issue.
Worse, though, is what happens when the character i appears in the input and is not preceded by e. Consider the line #include <stdio.h>: you start with index as 1; that is an i, so you decrement index, but wordChar[0] is not an e, so you don't increment it again, but the end of the loop does, so the loop checks index 1 again, and keeps on going around the loop testing that the i is i and # is not e for a long time.
There's no reason to decrement and then increment index; just use:
if (wordChar[index-1] == 'e')
combinationTimes++;
With those fixed, your code behaves. You trouble was largely that you were using an array that was not big enough (being size 0), and you were overwriting quasi-random memory with the data you were reading.
#include <stdio.h>
int main(void)
{
int index = 0;
int combinationTimes = 0;
int total = 0;
int userInput;
char wordChar[4096];
printf("please enter your input:\n");
while ((userInput = getchar()) != '#' && userInput != EOF)
{
if (userInput == '\n')
continue;
wordChar[index] = userInput;
index++;
total++;
}
printf("total: %d\n", total);
for (index = 1; index < total; index++)
{
if (wordChar[index] == 'i')
{
if (wordChar[index-1] == 'e')
combinationTimes++;
}
}
printf("number of combination is: %d\n", combinationTimes);
return 0;
}
Note that you could reasonably write the nested if as:
if (wordChar[index] == 'i' && wordChar[index-1] == 'e')
combinationTimes++;
change your wordChar array value.
int main(void)
{
int index = 0;
int combinationTimes = 0;
int total = 0;
char userInput;
//char wordChar[index]; // index = 0
char wordChar[255]; // should change the value of array.
printf("please enter your input:\n");
while ((userInput = getchar()) != '#')
{
if (userInput == '\n')
continue;
wordChar[index] = userInput;
index++;
total++;
}
for (index = 1; index < total; index++)
{
if (wordChar[index] == 'i')
{
if (wordChar[--index] == 'e')
{
combinationTimes++;
++index;
}
}
}
printf("number of combination is: %d", combinationTimes);
return 0;
}
or maybe you can use pointer and then use malloc and realloc.