Error code randomly appears when trying to run slot machine program - c

I am writing a program for a basic slot machine, randomly generating numbers and displaying the corresponding "symbols" for them from an array. The program executes most of the time but randomly I get an error code -1073741819 (0xC0000005). I'm extremely new to C so I'm unfamiliar with a lot of things, including what exactly can be causing this error in my code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL));
char *symbols[] = {"Pineapple", "Kiwi", "Orange", "Lime", "Peach",
"Lemon", "Pear", "Banana", "Cherry", "Grape", "Blueberry",
"Blackberry", "Apricot"};
int num1, num2, num3;
int balance;
printf("Enter initial balance (in cents): ");
scanf("%d", &balance);
num1 = (rand() % (13 - 0 + 1)) + 0;
num2 = (rand() % (13 - 0 + 1)) + 0;
num3 = (rand() % (13 - 0 + 1)) + 0;
printf("%s ", symbols[num1]);
printf("%s ", symbols[num2]);
printf("%s ", symbols[num3]);
printf("\n");
if ((num1 == num2) && (num1 == num3))
{
printf("Congratulations! You have won $1");
balance += 100;
printf("\n");
}
balance -= 5;
printf("Remaining Balance: %d", balance);
return 0;
}
The error as I said happens randomly and I haven't been able to reliably reproduce it. Sometimes only 1/3 fruit names prints and I get the error code, sometimes it's 2 and sometimes none prints.

This:
num1 = (rand() % (13 - 0 + 1)) + 0;
Is the same as:
num1 = rand() % 14;
Which means you're generating a number from 0 to 13. Your symbols array has 13 elements with indexes from 0 to 12. So when you randomly generate the value 13, you're reading past the end of the array. Doing so invokes [undefined behavior]9https://en.wikipedia.org/wiki/Undefined_behavior), which in this case causes your program to crash.
Change that line and the two that follow to:
num1 = (rand() % 13;
num2 = (rand() % 13;
num3 = (rand() % 13;
That way you get a number from 0 to 12.

The statement (rand() % (13 - 0 + 1)) + 0; is equivalent to rand() % 14 which will generate random numbers from 0-13 INCLUSIVE. The problem is that you only have 13 strings, so when the rng spits out a 13, the fruit at index 13 doesn't exist.
This can be fixed by either adding another fruit or by changing your rng to rand() % 13

You are randomly accessing an invalid 14th element of symbols array (which has 13 elements).
When you write
num1 = (rand() % (13 - 0 + 1)) + 0;
you are trying to calculate symbols index. But this could lead to index 13... and symbols[13] does not exist, and it will translate in accessing a memory location you are not supposed to access.
Write simply
num1 = rand() % 13;
and everything will be fine.

Related

A function that takes an integer and inserts zeros between its digits

The function should take the address of the integer and modify it by inserting zeros between its digits. For example:
insert_zeros(3) //3
insert_zeros(39) //309
insert_zeros(397) //30907
insert_zeros(3976) //3090706
insert_zeros(39765) //309070605
My code:
#include <stdio.h>
#include <math.h>
void insert_zeros(int* num);
int main() {
int num;
printf("Enter a number:");
scanf("%d", num);
insert_zeros(&num);
printf("Number after inserting zeros: %d", num);
return 0;
}
void insert_zeros(int* num){
int count = 0;
int tmp = *num;
//Count the number of digits in the number
while(tmp != 0){
tmp /= 10;
count++;
}
//calculating the coefficient by which I will divide the number to get its digits one by one
int divider = (int)pow(10, count-1);
int multiplier;
tmp = *num;
*num = 0;
/*
The point at which I'm stuck
Here I tried to calculate the degree for the number 10
(my thought process and calculations are provided below)
*/
(count >= 3)? count += (count/2): count;
//the main loop of assembling the required number
while (count >= 0){
multiplier = (int)pow(10, count); //calculating a multiplier
*num += (tmp / divider) * multiplier; //assembling the required number
tmp %= divider; //removing the first digit of the number
divider /= 10; //decreasing divider
count -= 2; //decreasing the counter,
//which is also a power of the multiplier (witch is 10)
}
}
My idea consists of the following formula:
For number "3" I shold get "30" and it will be:
30 = (3 * 10^1) - the power is a counter for number "3" that equals 1.
For number "39" it will be "309":
309 = (3 * 10^2) + (9 * 10^1)
For number "397" it will be "30907":
30907 = (3 * 10^4) + (9 * 10^2) + (7 * 10^0)
For number "3976" it will be "3090706":
3090706 = (3 * 10^6) + (9 * 10^4) + (7 * 10^2) + (6 * 10^0) - with each iteration power is decreasing by 2
For number "39765" it will be "309070605":
309070605 = (3 * 10^8) + (9 * 10^6) + (7 * 10^4) + (6 * 10^2) + (5 * 10^0)
And so on...
For a 3-digit number, the start power should be 4, for a 4-digit number power should be 6, for a 5-digit it should be 8, for 6-digit it should be 10, etc.
That algorithm works until it takes a 5-digit number. It outputs a number like "30907060" with an extra "0" at the end.
And the main problem is in that piece of code (count >= 3)? count += (count/2): count;, where I tried to calculate the right power for the first iterating through the loop. It should give the right number to which will be added all the following numbers. But it only works until it gets a 5-digit number.
To be honest, so far I don't really understand how it can be realized. I would be very grateful if someone could explain how this can be done.
As noted in comments, your use of scanf is incorrect. You need to pass a pointer as the second argument.
#include <stdio.h>
#include <math.h>
int main(void) {
int num;
scanf("%d", &num);
int num2 = 0;
int power = 0;
while (num > 0) {
num2 += (num % 10) * (int)pow(10, power);
num /= 10;
power += 2;
}
printf("%d\n", num2);
return 0;
}
There's an easy recursive formula for inserting zeros: IZ(n) = 100*IZ(n/10) + n%10.
That gives a very concise solution -- here the test cases are more code than the actual function itself.
#include <stdio.h>
#include <stdint.h>
uint64_t insert_zeros(uint64_t n) {
return n ? (100 * insert_zeros(n / 10) + n % 10) : 0;
}
int main(int argc, char **argv) {
int tc[] = {1, 12, 123, 9854, 12345, 123450};
for (int i = 0; i < sizeof(tc)/sizeof(*tc); i++) {
printf("%d -> %lu\n", tc[i], insert_zeros(tc[i]));
}
}
Output:
1 -> 1
12 -> 102
123 -> 10203
9854 -> 9080504
12345 -> 102030405
123450 -> 10203040500
Adapting some code just posted for another of these silly exercises:
int main() {
int v1 = 12345; // I don't like rekeying data. Here's the 'seed' value.
printf( "Using %d as input\n", v1 );
int stack[8] = { 0 }, spCnt = -1;
// Peel off each 'digit' right-to-left, pushing onto a stack
while( v1 )
stack[ ++spCnt ] = v1%10, v1 /= 10;
if( spCnt == 0 ) // Special case for single digit seed.
v1 = stack[ spCnt ] * 10;
else
// multiply value sofar by 100, and add next digit popped from stack.
while( spCnt >= 0 )
v1 = v1 * 100 + stack[ spCnt-- ];
printf( "%d\n", v1 );
return 0;
}
There's a ceiling to how big a decimal value can be stored in an int. If you want to start to play with strings of digits, that is another matter entirely.
EDIT: If this were in Java, this would be a solution, but the problem is in C, which I'm not sure if this can convert to C.
This may be a lot easier if you first convert the integer to a string, then use a for loop to add the zeros, then afterward reconvert to an integer. Example:
int insert_zeros(int num) {
String numString = Integer.toString(num);
String newString = "";
int numStringLength = numString.length();
for (int i = 0; i < numStringLength; i++) {
newString += numString[i];
// Only add a 0 if it's not the last digit (with exception of 1st digit)
if (i < numStringLength - 1 || i == 0) newString += '0';
}
return Integer.parseInt(newString);
}
I think this should give you your desired effect. It's been a little bit since I've worked with Java (I'm currently doing JavaScript), so I hope there's no syntax errors, but the logic should all be correct.

Generating random numbers in conditions

I'm trying to generate three random numbers in three conditions and the three numbers must be from 0 to 100:
an odd number
an even number
a number larger than 50
Here is my code:
#include <stdio.h>
#include <time.h>
int main (void) {
int num1 = 0, num2 = 0, num3 = 0;
srand(time(NULL));
num1 = rand() % 100;
while (num1 % 2 != 0) {
num1 = rand() % 100;
}
num2 = rand() % 100;
while (num2 % 2 == 0) {
num2 = rand() % 100;
}
num3 = rand() % 100;
while (num3 > 50) {
num3 = rand() % 100;
}
printf("your numbers\n%d\n%d\n%d\n", num1, num2, num3);
return 0;
}
the compiler answers me:
warning: implicit declaration of function 'srand' [-Wimplicit-function-declaration]
srand(time(NULL));
and I do have stand in the requirements of the school:
it must be in loops
I cannot use break nor TRUE nor FALSE
Your srand() issue is simply because you haven't included stdlib.h, where that call (and rand() for that matter) is declared.
In any case, there's no real need to use a loop while discarding "invalid" numbers, you can use math for this :-) (a)
Assuming 0 to 100 inclusive:
num1 = rand() % 50 * 2 + 1 // 1, 3, 5, ..., 99
num2 = rand() % 51 * 2 // 0, 2, 4, ..., 100
num3 = rand() % 50 + 51 // 51, 52, ..., 100
For num1, the % gives a value 0..49 which, when doubled and incremented, gives you an odd number in the desired range. The second one is similar but with the range expanded slightly since there are even numbers at both ends. The third simply gives a number 0..49 which maps to 51..100 when 51 is added.
Similar results can be obtained if the range is only half-open (0..99 inclusive):
num1 = rand() % 50 * 2 + 1 // 1, 3, 5, ..., 99
num2 = rand() % 50 * 2 // 0, 2, 4, ..., 98
num3 = rand() % 49 + 51 // 51, 52, ..., 99
If, for some bizarre reason it has to use a loop (despite the inefficiencies), you have some problems with the conditions you use - they're basically all the wrong sense. In other words, you want (for example) the first loop to run while the number is even so that it will eventually produce an odd number.
You should be able to use something like the following. Each block consists of initialising the variable to a value that will force the loop to start then the loop that continues until a value with the desired properties is found:
int num1 = 0; // even forces loop entry
while ((num1 % 2) == 0) // wait for odd
num1 = rand() % 100;
int num2 = 1; // odd forces loop entry
while ((num2 % 2) == 1) // wait for even
num2 = rand() % 100;
int num3 = 1; // 50 or less forces loop entry
while (num3 <= 50) // wait for 51+
num3 = rand() % 100;
All of these limit the range of potential values to 0..99 inclusive, If you want to include 100, simply change the expressions to be rand() % 101.
(a) I'm actually not a fan of these sorts of limitations when set by educators. They're actually teaching inefficient ways to code. It would be far better if it was something that was a lot harder to do with a simple mathematical operation (like ensuring the number was neither 11, 17, 43 nor 97).
I suspect you could find a mathematical way to detect that but it would be far easier just to use a series of conditionals. Now I'm just waiting for someone to show me up by providing the mathematical formula for detecting those four :-)
There are some mistakes in the posted code:
a missing #include <stdlib.h>
the first test should be while (num1 % 2 == 0)
the second test should be while (num2 % 2 != 0)
the third test should be while (num3 <= 50)
Here is a modified version with loops but without looping :)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (void) {
int num1, num2, num3;
srand(time(NULL)); /* or better randomness with srand(clock()); */
num1 = 1 + rand() % 50 * 2; /* 1, 3, ..., 99 */
while (num1 % 2 == 0) {
num1 = rand() % 100;
}
num2 = rand() % 50 * 2; /* 0, 2, ..., 98 */
while (num2 % 2 != 0) {
num2 = rand() % 100;
}
num3 = 51 + rand() % 49; /* 51, 52, ..., 99 */
while (num3 <= 50) {
num3 = rand() % 100;
}
printf("your numbers\n%d\n%d\n%d\n", num1, num2, num3);
return 0;
}
For those interested, both gcc and clang detect that the first 2 loops can be eliminated, but not the third as they do not make the assumption that rand() return a non negative number: https://godbolt.org/z/ucpV-y
You need to #include <stdlib.h> to get rid of this warning.
However, there's a bigger problem with your code: you have all the conditions inverted.
This will loop until the number is odd:
while (num1 % 2 != 0) {
This will loop until the number is even:
while (num2 % 2 == 0) {
And this will loop until the number is less than or equal to 50:
while (num3 > 50) {
To fix that, simply invert the conditions:
while (num1 % 2 == 0) { /* until we get an even number */
/* ... */
while (num2 % 2 != 0) { /* until we get an odd number */
/* ... */
while (num3 <= 50) { /* until num3 is greater than 50 */

Why is line number 22 necessay?

I am trying to generate all the Armstrong number from 0 to 999. I can't understand why my code doesn't work if I remove the sum=0; statement at the bottom of the program (line 22).
#include<stdio.h>
#include<conio.h>
int main()
{
int i, n=999, rem, num, sum=0;
for(i=0; i<n; i++)
{
num=i;
while(num != 0)
{
rem = num%10;
num = num/10;
sum = sum+(rem*rem*rem);
}
if (sum == i)
{
printf("%d\n", sum);
}
sum=0;
}
return 0;
}
You're just resetting the sum so that each iteration of the for loop has a fresh, zeroed sum.
If you don't do this, each iteration of the loop will keep sum as whatever value it was from the prior iteration, thus compounding the summation and giving incorrect values!
As mentioned in the comments, it's traditionally easier to understand if this is done at the beginning of the loop, and in conjunction with that, it's better still to keep variable scopes as narrow as possible, e.g.:
#include <stdio.h>
int main()
{
for(int i = 0; i < 999; i++)
{
int sum = 0;
int num = i;
while(num != 0)
{
int rem = num % 10;
num = num / 10;
sum = sum + (rem * rem * rem);
}
if (sum == i)
{
printf("%d\n", sum);
}
}
return 0;
}
In the for loop, the first usage of sum is sum = sum + (rem*rem*rem);, so if you do not want to use the value of the sum from the previous iteration, you have to reset its value to zero at the beginning of each iteration of the for loop. In your code, you reset its value to zero just before the for loop, and at the end of each iteration (line 22), which does the trick.
An Armstrong number N is where the sum of the individual digits (say, A, B, C), raised to the power of the number of digits, equals the number itself.
N = A^3 + B^3 + C^3
So to calculate this for 0-999, you need a loop. In each iteration of the loop you need to start the summation over again from 0. Take i=10 and i=11 from your loop as an example. Neither is an Armstrong number, but they should be:
i=10: 1^2 + 0^2 = 1
i=11: 1^2 + 1^2 = 2
Without resetting sum, you're using the results of the previous numbers calculation:
i=10: 1^2 + 0^2 + 9^1 (+ 8^1 + 7^1 + ...) ≠ 1
i=11: 1^2 + 1^2 + (1^2 + 0^2 + 9^1) + ... ≠ 2

Decryption - Get back the number after splitting C programming

I've just did an encryption using a simple C code. The encryption works like this, "Your application should read a 4 digit integer entered by the user and replace each digit with the result of adding 7 to the digit and getting the remainder after diving the new value by 10:
Let say I've entered 1234, the value after encryption will be 8,9,0,1.
I'm doing the encryption with the following code below:
num1 = ((digits/1000) + 7) % 10;
num2 = ((digits/100) + 7) % 10;
num3 = ((digits/10) + 7) % 10;
num4 = ((digits/1) + 7) % 10;
Now I would like to do a decryption, getting back the value I've entered. I'm wondering if I'm able to do a reverse modulo? A backwards calculation for %?
Meaning if a = 3 + 4, a = 7.. So what is 7 = b + 4 which is b = 7-4. I'm
What I've attempted so far is this:
dNum1= (digits/1000) % 10;
dNum2= (digits/100) %10;
dNum3= (digits/10) %10;
dNum4= (digits % 10) ;
The question is now: How do I retrieve the original value from the decrypted value(8,9,0,1)? (Original Value: 1234)
Since you encoded each digit by adding 7, you need to decode by subtracting 7. Then if the value is negative, add 10 to get back the expected value.
num1 = (digits/1000) - 7;
num2 = (digits/100) - 7;
num3 = (digits/10) - 7;
num4 = (digits % 10) - 7;
if (num1 < 0) num1+=10;
if (num2 < 0) num2+=10;
if (num3 < 0) num3+=10;
if (num4 < 0) num4+=10;
EDIT:
Better yet, you can add 3 and then mod by 10, which does the same thing. Thanks to psmears for suggesting this.
num1 = ((digits/1000) + 3) % 10;
num2 = ((digits/100) + 3) % 10;
num3 = ((digits/10) + 3) % 10;
num4 = ((digits/1) + 3) % 10;
EDIT2:
If you're translating the decoded digits directly from the encoded digits without moving the values back to digits first, do this:
dNum1 = (num1 + 3) % 10;
dNum2 = (num2 + 3) % 10;
dNum3 = (num3 + 3) % 10;
dNum4 = (num4 + 3) % 10;
that's an interesting question #stack. One thing I see is that you are using individual statements to assign values to num1,num2,num3,num4
but every encryption follows a defined pattern and implicit is that
every decryption does
And if you are successful in finding such pattern(Which I prefer to say mystery!), then these kind of encryption are near solved!
So I decided to find the pattern and I was successful in finding it for your encryption. ones you find pattern, for loop is very useful to repeat the process and thus encode given number.(same for the decoding too)
Note: I Don't know whether you require such a solution, but this is more useful as there are less number of variables which is a characteristic of any good program. and this code is only for 4 digit numbers... feel free to ask me if you want to extend it to n digited numbers :)
so! Here is my code:
#include<stdio.h>
#include<math.h>
int main()
{
//encryrption
int num,num1,i,e=0,d=0;
printf("enter 4 digit number:\n");
scanf("%d",&num);
num1=num;
for(i=3;i>=0;i--)
{
num1=(num)/(pow(10,i));
num1=(num1+7)%10;
e=(10*e)+num1;
}
printf("encryption = %d\n",e);
//decryption:
for(i=3;i>=0;i--)
{
num1=e/pow(10,i);
num1=((num1-7)%10);
d=(10*d)+num1;
}
printf("decryption = %d",d);
return 0;
}

Program Freezing - Luhn's Algorithm

I am hoping someone can help me with this. I am a complete and utter C newbie.
This is for a school assignment in a class on C (just plain old C, not C# or C++), and the professor is insistent that the only compiler we're allowed to use is Borland 5.5.
The general assignment is to run an algorithm that can check the validity of a credit card number. I've successfully gotten the program to pick up the user-input CC number, then portion that number out into an array. It prints out mostly what I want.
However, when I entered the last function (the one I commented as such) and then compiled, the program just started to hang. I have no idea what could be causing that.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//global variables declared.
//in an earlier version, I was going to use multiple functions, but I couldn't make them work
float array[16];
double num, ten;
int i, a, b, x, y, check;
int main()
{
ten = 10;
//pick up user-input number
printf("Enter your credit card number\n>");
scanf("%lf", &num);
//generate the array
for (i = 15; i >= 0; i--)
{
array[i] = fmod(num, ten);
num /= 10;
printf("Array is %1.1lf\n", array[i]);
}
//double every other number. If the number is greater than ten, test for that, then parse and re-add.
//this is where the program starts to hang (I think).
{for (i = 2; i <= 16; i + 2)
{
array[i] = array[i] * 2;
if (array[i] >= 10)
{
a = (int)array[i] % 10;
b = (int)array[i] / 10;
array[i] = a + b;
}
}
printf("%f", array[i]);
}
//add the numbers together
x = array[2] + array[4] + array[6] + array[8] + array[10] + array[12] + array[14] + array[16];
y = array[1] + array[3] + array[5] + array[7] + array[9] + array[11] + array[13] + array[15];
check = x + y;
//print out a test number to make sure the program is doing everything correctly.
//Right now, this isn't happening
printf("%d", check);
return 0;
}
for (i = 2; i <= 16; i + 2)
should be
for (i = 2; i <= 16; i = i + 2)
or
for (i = 2; i <= 16; i += 2)
As you have it, the value of i is never modified, so the loop never terminates.
You declare your array
array[16] so array[0] .. array[15]
In the second for loop you have
when i = 16 array[16]!
valter

Resources