I just started learning C++ and am trying to learn how to use scanf and printf for faster input and output. Here is the code I'm currently working on:
#include <stdio.h>
using namespace std;
int main() {
int time, record;
double down, loan;
while (scanf("%d %lf %lf %d", &time, &down, &loan, &record) != EOF) {
double value = down + loan;
double owed = loan;
double payment = owed/time;
// current simulated month and depreciation
int rday, c = 0;
double temp, dep;
bool found = false;
// finds value and owed after records
while (!found && record > 0) {
scanf("%d %lf", &rday, &temp);
// adjusts value and owed to day before listed on record
while (!found && c <= rday) {
if (c == rday) {
dep = temp;
}
value *= 1 - dep;
if (c > 0) {
owed -= payment;
}
c++;
// determines if found date
if (owed < value) {
found = true;
}
}
record--;
}
// finds point where owed < value
while (!found && value < owed) {
value *= 1 - dep;
owed -= payment;
c++;
}
if (c - 1 == 1) {
printf("%d month\n", c - 1);
}
else {
printf("%d months\n", c - 1);
}
}
return 0;
}
When I run this on Code::Blocks, it prints the correct answers, but the outermost while loop doesn't terminate even when I enter CTRL+Z (I am using Windows). Here is my input:
30 500.0 15000.0 3
0 .10
1 .03
3 .002
12 500.0 9999.99 2
0 .05
2 .1
60 2400.0 30000.0 3
0 .2
1 .05
12 .025
-99 0 17000 1
Here is an image of the what happens:
Error
I've tried changing the loop condition to scanf("%d %lf %lf %d", &time, &down, &loan, &record) == 4, but the same problem happens. Could someone please explain what the issue with my code is?
In the line
while (scanf("%d %lf %lf %d", &time, &down, &loan, &record) != EOF)
you expect 4 variables to be read into when the read is successful. When scanf is able to successfully extract the data from stdin for all the arguments, it will return 4. Change the check to use that number.
while (scanf("%d %lf %lf %d", &time, &down, &loan, &record) == 4)
It's because scanf never returns EOF, so the termination condition is never satisfied.
Thanks for the suggestions and answers, everyone! I figured out the bug. Kind of embarrassing, but it turns out the issue was with the last line of input.
Related
I've made a program where the user inputs a x coordinate and a y coordinate, If the user inputs a letter I want the input to be repeated until a valid input has been inputed. After 3 attempts the program will end. However every time I run the program and input a test character the program skips the scanf function and doesn't test the nested if loops, I've tried the adding a space in the scanf function but That doesn't seem to work at all. Would appreciate some help thank you :)
Code:
printf("Insert first vector:\n");
vector1 = scanf(" %f %f",&x1,&y1);
printf("x1 %f y1 %f \n",x1,y1);
if(vector1 == 0)
{
printf("Invalid input\n");
printf("Insert first vector; \n");
vector2 = scanf(" %f %f",&x1,&y1);
if(vector2 == 0)
{
printf("Invalid input\n");
printf("Insert first vector; \n");
vector3 = scanf(" %f %f",&x1,&y1);
if(vector3 == 0)
{
printf("Invalid input \n");
x1=WRONG;
I'm assuming that you're using C Language.
int count = 1;
do {
printf("Insert First Vector: ");
fflush(stdin);
vector1 = scanf("%f %f", &x1, &y1);
count++;
} while (vector == 0 && count <= 3);
Try using above code.
I'm using do while loop just for sake of simplicity.
If I enter an amount of 5 players (5 elements in the score[] array) in the scanf("%d", &numPlayers) the for loop cycles the players all the way up to player 5 (element 4 of score[]), and then jumps to the winMsg function. The score of that element is a large value, even though I set all the score[] element's to 0 in the first for loop. If I enter 6 or more elements, the second for loop never executes. Program runs no problem with 4 or less elements in score[]. I am using gedit and terminal in Ubuntu. Any ideas? Fairly new to programming. I appreciate any help.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
int rollDie(){
return (rand()%6 + 1);
}
void winMsg(int winRoll, int player, int winScore){
printf("Congratulations Player %d! Your winning roll was a %d, putting your score at %d!\n\nGame Over\n\n", player + 1, winRoll, winScore);
return;
}
int main(){
srand(time(NULL));
int numPlayers = 0;
int roll = 0;
int i = 0;
int score[numPlayers];
char choice[2];
printf("Welcome to the \"Roll to Win\" game. Each roll adds to the current player's score, according to the die's number. A roll of 1 will cause the player to recieve no points that round, and then be skipped to the next player. First player to reach 100 or over wins! Please enter number of players: \n\n");
scanf("%d", &numPlayers);
printf("\n");
while (numPlayers >= 100 || numPlayers <= 0){
printf("Please enter a number of players less than 100, greater than 0.\n\n");
scanf("%d", &numPlayers);
printf("\n");
}
for (i = 0; i < numPlayers; ++i){
score[i] = 0;
printf("Set Player %d score to %d.\n", i + 1, score[i]);
}
printf("Starting with Player 1.\n\n");
for (i = 0; i < numPlayers; ++i){
roll = rollDie();
if (roll == 1){
printf("Player %d rolled a 1. Skipping turn. Current score: %d.\n\n", i + 1, score[i]);
}
else{
do{
score[i] += roll;
if (score[i] >= 100){
winMsg(roll, i, score[i]);
exit(0);
}
printf("Player %d rolled a %d, continue rolling (enter r to roll, or sr to stop rolling)? Current score: %d.\n\n", i + 1, roll, score[i]);
scanf("%s", choice);
printf("\n");
while ((strcmp ("r",choice) != 0) & (strcmp ("sr",choice) != 0)){
printf("Please enter a correct selection (enter r to roll, or sr to stop rolling).\n\n");
scanf("%s", choice);
printf("\n");
}
if (strcmp ("sr",choice) == 0){
printf("Player %d decided to stop rolling. Continuing to next player.\n\n", i + 1);
break;
}
roll = rollDie();
if (roll == 1){
printf("Player %d rolled a 1. Skipping turn. Current score: %d.\n\n", i + 1, score[i]);
break;
}
} while (strcmp (choice,"r") == 0);
}
if (i == numPlayers - 1){
i = -1;
}
}
}
Notice, that you set the size when initializing array before it is known, therefore you end up with garbage.
Doing int score[numPlayers]; and later scanf("%d", &numPlayers); will not do what you think it does.
it is not standard C++ to have a static array size which is not a constant,if you want that behavior you should use std::vector.
Even if this is working for you, then you should first ask for the number of players and then create the array. i.e
scanf("%d", &numPlayers);//first
....
int score[numPlayers];//then
My professor gave me a asignment to write a 16 matches Nim game.
One part of a task is to make PC to make moves as well. So, I tried to solve the problem by using SRAND but PC picked the same row and the same amount of sticks. What is more, PC also takes emty rows wich and hits the wall when he takes the zero massive.
So, thats is what I hve already done. Any thoughts?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define row 4
int main()
{
int theChecker = 1, sticks[row] = {1,3,5,7}, stickSum, i, choiceRow, choiceStick, pcRow, pcStick;
char answer;
do
{
printf("\n\n\t ************ \n");
printf("\t *THE NIM GAME* \n");
printf("\t ************ \n\n");
stickSum = sticks[0] + sticks[1] + sticks[2] + sticks[3];
while(stickSum > 0)
{
printf("\nStick log:\n");
for(i = 0; i < row; i++)
printf("Row %d: %d\n", i+1, sticks[i]);
printf("\n");
if(theChecker == 1)
{
printf("Choose a row: ");
scanf("%d", &choiceRow);
printf("Choose a sick: ");
scanf("%d", &choiceStick);
while((choiceRow <= 0) || (choiceRow > 4) || (sticks[choiceRow - 1] < choiceStick) || (choiceStick == 0))
{
printf("\n\t !!!ERROR!!!\n\tInvalid row or stick\n\nCheck stick log above\n\n");
printf("Choose a row: ");
scanf("%d", &choiceRow);
printf("Choose a sick: ");
scanf("%d", &choiceStick);
}
sticks[choiceRow-1] -= choiceStick;
stickSum -= choiceStick;
}
else //pc move starts-------------------------------------------
{
while(((pcRow <= 0) || (pcRow > 4)) && sticks[choiceRow - 1] == 0)
{
time_t seconds;
seconds = 0;
time(&seconds);
srand((unsigned int)seconds);
pcRow = rand() % 4;
}
printf("PC ROW: %d\n", pcRow);
while((sticks[pcRow - 1] < pcStick) || (pcStick == 0))
{
time_t seconds2;
seconds2 = 0;
time(&seconds2);
srand((unsigned int)seconds2);
pcStick = rand() % 16;
}
printf("PC STICK: %d\n\n", pcStick);
sticks[pcRow-1] -= pcStick;
stickSum -= pcStick;
}
if((theChecker == 1) && (stickSum == 0))
printf("\n\n!!!GAME OVER!!! You took the last stick!!!\n\n");
else if((theChecker == 2) && (stickSum == 0))
printf("\n\n!!!CONGRATS!!! You won!!!\n\n");
theChecker++;
if(theChecker == 3)
theChecker -= 2;
}
printf("\nPress r to restart the game or any key to end the game: ");
scanf("%c", &answer);
printf("\n");
}
while(answer == 'r');
return 0;`enter code here`
}
Don't call srand() more than once, it's used to initialize the random seed, which you are always initializing to the same value, the internal state gets reset over and over, always producing the same pseudo-random values.
I say that you always pass the same seed, because time() has seconds resolution, and in once second, the whole game was played and terminated.
You just need a call to srand() at the beginning of the program to prevent the program from choosing the same values across runs of the program, not in the same run.
I don't understand why my loop stops, i want the user to keep asking for a number and find its square root. If the user enters negative number THEN it should stop. please help, cant see my mixtake...
CODE:
int main (void)
{
double number, calc;
printf ("Enter a number to find its sqrt");
while (1)
{
scanf ("%lf",&number);
if (number > 0)
{
calc = sqrt(number);
printf ("The sqrt of %lf is %lf", &number, &calc);
}
else
printf ("Try again:\n");
}
return (0);
}
Not allowed to answer but, I see thanks you two!!
(Didnt know i must exist loop)
You must exit the loop somewhere.
if(number < 0)
break;
Alternatively you can do this (which would be better in this case):
number = 0;
while(number >= 0)
{
....
}
I have looking all over forums to try and understand this issue. The reasons I cannot fully understand the issue and why I cannot find a solution is because I am fairly new with C++ and I do not understand the error message.
This is my code in C++ that finds the number of possibilities from permutation or combination formulas. Every I try and compile and run, I get messages that say:
First-chance exception at 0x6a8613af (msvcr100d.dll) in
Combinations_Permutations.exe: 0xC0000005: Access violation reading
location 0x00000005. Unhandled exception at 0x6a8613af (msvcr100d.dll)
in Combinations_Permutations.exe: 0xC0000005: Access violation reading
location 0x00000005.
I've learned on many other forums that the "access violation reading location 0x00..." could definitely indicate null pointer. But I cannot see where I encounter such a null issue. Maybe my variables are being accessed globally, where they are not YET initialized?
Here is my code, I have been at it for a while... like I said I'm fairly new. So please inform me of my mistake(s). Thank you.
My code:
#include <iostream>
#include "conio.h";
using namespace std;
int run_combination(int n, int r);
int run_permutation(int n, int r);
int solve_factorial(int f);
int f_value = 1; //factorial value used recursively
int n_input, r_input;
char choice;
char order;
void main(){
//if user types choice as 'q', while loop ends
while(choice != 'q'){
printf("How many values? (1-9) \n");
printf("User: ");
cin >> n_input;//user input for variable n
printf("n_input: %i", n_input);
printf("\nHow many will be chosen at a time out of those values? (1-9)\n");
printf("User: ");
cin >> r_input; //user input for variable r
printf("\nDoes order matter? (y/n)\n");
printf("User: ");
cin >> order; //'y' if order is taken into consideration(permutation)
//'n' if order it NOT taken into consideration(combination)
int solution = 0; //temporary variable that represents the solution after running
//n and r through the permutation or combination formula
//if user input values for n and r are in between 1 and 9, then run
//combination or permutation
if (n_input <= 9 && n_input >= 1 && r_input <= 9 && r_input >= 1){
if (order == 'y')
solution = run_permutation(n_input, r_input);
else if (order == 'n')
solution = run_combination(n_input, r_input);
else
printf("\nError. Please type 'y' or 'n' to determine if order matters.\n");
//if n < r, run_permutation or run_combination returns 0
if (solution == 0){
printf("Error! You can't choose %i values at a time if there \n",
"are only %i total values. Type in new values next loop \n.", r_input, n_input);
}
else
printf("Number of possibilities: %s", solution);
}
else{ //else error message if numbers are out of range...
printf("Next loop, type in values that range from 1 to 9.\n");
}
//option 'q' to quit out of loop
printf("Type 'q' to quit or enter any key to continue.\n");
printf("User: ");
cin >> choice;
}
_getch();
}
/*
Returns solved combination of parameters n and r
Takes the form: n! / r!(n-r)!
*/
int run_combination(int n, int r){
if (n < r) //solution is impossible because you can't choose r amounnt at a time if r is greater than n
return 0;
int n_fac = solve_factorial(n); //n!
int r_fac = solve_factorial(r); //r!
int nMinusr_fac = solve_factorial(n-r); //(n-r)!
int solve = ((n_fac) / ((r_fac)*(nMinusr_fac))); // plugging in solved factorials into the combination formula
return solve;
}
int run_permutation(int n, int r){
if (n < r)
return 0;
int n_fac = solve_factorial(n);
int nMinusr_fac = solve_factorial(n-r);
int solve = ((n_fac) / (nMinusr_fac)); //plugging in factorials into permutation formula
return solve;
}
int solve_factorial(int f){
if (f-1==0 || f == 0){ //if parameter f is 1 or 0, return 1
int temp = f_value;
f_value = 1; //reset f_value so that f_value remains 1 at the start of every new factorial
return temp;
}
else{ //else multiply f_value by f-1
f_value *= f;
return solve_factorial(f-1);
}
}
This is a mistake:
printf("Number of possibilities: %s", solution);
solution is an int, not a null terminated string: use %d.
Using std::cout which is typesafe, instead of printf(), would have prevented this error:
std::cout << "Number of possibilities: " << solution;
The problematic line is:
printf("Number of possibilities: %s", solution);
You're telling printf that solution is a char*, and so it tries to dereference (char*)solution to print the contents of the "C-string" (presumably when solution has the value 5 in the case of your particular error message).
Change %s to %d, or use std::cout instead of printf to gain type-safety and avoid this sort of issue in the first place.