Compiling C file is fine, but exe file displays nothing - c

I've been trying to figure out what's going on, but it's driving me nuts. I have this script here, it compiles fine (I'm using GCC), but when I try to run the compiled exe, the terminal just pauses for a brief moment and exits. I have no clue what's going on, any help would be appreciated.
// not sure what's on
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "extra.h"
int RanNum(int StartNum, int StopNum);
int main() {
printf("Hey\n");
int magicNum, guess, choice;
do {
printf("Guess the right number: ");
scanf("%d", &choice);
guess = 1;
magicNum = RanNum(3,10);
if (choice == magicNum){
printf("You win! \n");
break;
} else {
int rem = (3 - guess);
printf("\nYou have %d tries remaining \n", rem);
}
guess++;
} while (guess <= 3);
if (guess > 3) {
printf("You lost... We can try again...\n");
}
return 0;
}
int RanNum(int StartNum, int StopNum){
int *list;
int Divided;
int range = StartNum - StopNum;
int RandArray[range];
for (int i=StartNum; i<StopNum; i++) {
for (int j=0; j<range+1; j++) {
RandArray[j] = i;
}
}
list = RandArray;
Divided = (StartNum+StopNum)/range;
return list[Divided];
}

RanNum runs into UB (undefined behavior) and a silent exit is one possible manifestation of UB.
int RanNum(int StartNum, int StopNum){ // <---- called with StartNum = 3, StopNum = 10
int *list;
int Divided;
int range = StartNum - StopNum; // <---- range = 3 - 10 = -7
int RandArray[range]; // <---- array of negative size *** UB
for (int i=StartNum; i<StopNum; i++) {
for (int j=0; j<range+1; j++) { // <---- after 'range' is fixed to be > 0
RandArray[j] = i; // <---- the last iteration j = range
} // <---- overruns the array bound *** UB
}
// ...
}
Once the first problems are fixed, there is another one with the main loop.
int magicNum, guess, choice; // <---- 'guess' is defined but not initialized
do {
printf("Guess the right number: ");
scanf("%d", &choice);
guess = 1; // <---- 'guess' is initialized to '1` in each iteration
/* code that does not change or use 'guess' */
guess++; // <---- 'guess' was '1' and is now incremented to '2'
} while (guess <= 3); // <---- always true, so loop continues until number guessed

Related

segmentation fault (core dumped) gcc ubuntu

I was trying to make a simple function to make a group of number that user enters them, using pointer of pointer but i keep getting this error and its hard to tell where the problem is, if there any other option to use something else that tells me where the problem is instead of this weird error.
#include <stdio.h>
void BuildGroub(int** group,int* count){
int i=0;
int j;
printf("Enter the size of the group \n");
scanf("%d", &*count);
while(*count != 0){
printf("Enter the %d number of the group:\n", i);
j=0;
scanf("%d", &**(group+i));
while(**(group+i)!=**(group+j)){
j++;
}
if(j==i){
i++;
count--;
} else{
printf("you have already entered this number please try again: \n");
}
}
}
int main(){
int count;
int group[100];
int *groupptr = &group;
BuildGroub(&groupptr,&count);
for(int i=0;i<count;i++){
printf("%d, ", group[i]);
}
return 0;
}
With this question, you do not need to use double pointer. If you want to learn how to use the double pointer, you can google then there are a ton of examples for you, for example, Double Pointer (Pointer to Pointer) in C.
In BuildGroub you decrease the count pointer
if(j==i){
i++;
count--;
}
, but in the condition of while loop, you compare the value that count pointer points to. it seems strange.
while(*count != 0)
Even if you change count-- to (*count)--, it will decrease the number of elements that you enter to 0 when you get out of the while loop, then in main function:
for(int i=0;i<count;i++){} // count is equal to 0 after calling BuildGroub function if you use (*count--) in while loop.
You should use a temp value for while loop function, for example:
int size = *count;
while(size != 0){
...
if (i == j) {
i++;
size--;
}
}
You should use, for example, group[i] instead of *(group+i). It will be easier to read your code.
The code complete:
#include <stdio.h>
void BuildGroub(int* group,int* count){
int i=0;
int j;
printf("Enter the size of the group \n");
scanf("%d", count);
int size = *count;
while(size != 0){
printf("Enter the %d_th number of the group:\n", i);
j=0;
scanf("%d", &group[i]);
while(group[i] != group[j]) {
j++;
}
if(j==i){
i++;
size--;
} else{
printf("you have already entered this number please try again: \n");
}
}
}
int main(){
int count;
int group[100];
int *groupptr = group;
BuildGroub(groupptr,&count);
for(int i=0;i<count;i++){
printf("%d, ", group[i]);
}
return 0;
}
The test:
./test
Enter the size of the group
5
Enter the 0_th number of the group:
1
Enter the 1_th number of the group:
2
Enter the 2_th number of the group:
2
you have already entered this number please try again:
Enter the 2_th number of the group:
3
Enter the 3_th number of the group:
3
you have already entered this number please try again:
Enter the 3_th number of the group:
4
Enter the 4_th number of the group:
5
1, 2, 3, 4, 5,
If you want to use a double pointer, you need to change your function like this:
void BuildGroub(int** group, int* count) {
int i = 0;
int j;
printf("Enter the size of the group \n");
scanf("%d", &*count); //I think this is redundant but works.
while (*count != 0) {
printf("Enter the %d number of the group:\n", i);
j = 0;
scanf("%d", (*group + i)); //The content of group + i
while ( *( *group + i) != *(*group + j)) { //the content of the content
j++;
}
if (j == i) {
i++;
(*count)--; //The content decrement
} else {
printf("you have already entered this number please try again: \n");
}
}
}
But you have a big problem in main and it is because you are using the parameter count to decrement until zero inside the function. So when the function finish, count value is zero and you don't print anything... You need to change this, using a internal variable to make the count, and finaly, setting the parameter to be using in main.

Can I 'return' a result from the main variable?

So I have this exercise where I need to show the N first prime numbers, but I need to specifically create a function to know if the number is a prime number
#include <stdio.h>
#include <stdlib.h>
int prime(int num){
int cont,i,j=0,b;
b=num;
do{
j++;
i=0;
for(cont=1;cont<j;cont++){
if(j%cont == 0)
i++;
}
if(i == 1){
return(j);
c=j;
b--;
}
} while (b > 0);
}
int main(){
int *v,n,cont;
do{
printf("Input an integer: ");
scanf("%d",&n);
} while (n <= 0);
v = (int *)malloc(n * sizeof(int));
for(cont=0;cont<n;cont++){
v[cont] = prime(n);
}
for(cont=0;cont<n;cont++){
printf("%d ",v[cont]);
}
}
The problem with the way i've done this is that the variable J is aways being set to 0 when i call the function again, i've tried to set something like c=j so when the program return to the prime function it would have the 'previous' j value but it gets a weird random number. So I wanted to know if is there a way to 'return' the result in the main function to the prime function, i couldn't find anything that helped me, not that i could understand at least
Your function prime() is not working as intended and there are many other errors -
1) Since smallest prime is 2, variable cont should start from 2.
2) scanf need not be in a loop in this case
3) Enter values in v only when cont is confirmed a prime.
See this function prime2( not optimize though for clarity):
bool prime2(int n)
{
for(int i = 2 ; i<n-1;i++)
if( n% i == 0) return false;
return true;
}
int main(){
int *v,n,cont,cc=0;
printf("Input range: ");
scanf("%d",&n);
v = malloc(n * sizeof(int));
for(cont=2;cc<n;cont++){
if( prime2(cont) == true )
{
v[cc] = cont;
cc++;
}
}
for(cont=0;cont<n;cont++){
printf("%d ",v[cont]);
}
delete v;
}
Output:

Undefined reference error to function that is actually defined in C

I wrote this program to build a number diamond. The issue is that when I compile the program, it throws the error
build2.c:(.text+0x5): undefined reference to `get_input'
collect2: error: ld returned 1 exit status
I've tried for hours to figure out what exactly the problem is (e.g. if there is a spelling mistake or something similar), but the function call looks identical. I have attempted to rename it, write it as both a prototype and as an implementation, and nothing seems to work. Is there an issue that I'm not seeing?
//Define prior to main
int is_valid(int);
int get_input(void);
void print_pattern(int);
//Main
int main(void){
int diamond_size;
//diamond_size = get_input();
//value from get imput method used for diamond size
print_pattern(get_input());
return 0;
}
void print_pattern(int size){
int length, num, i, j;
//beginning of new diamond
printf("\n");
//Define each integer to work in layout of diamond
//First for loop fans out
for(i=1; i <= size; i += 2){
length = size-i+1;
num = 1;
printf("%*s", length," ");
for(j = 0; j < i; j++){
printf("%d ", num);
num++;
}
printf("\n");
}
//second for loop fans in
for(i=size-2; i >= 1; i -= 2){
length = size-i+1;
num = 1;
printf("%*s", length," ");
for(j = 0; j < i; j++){
printf("%d ", num);
num++;
}
printf("\n");
}
int is_valid(int value){
int rem;
//uses remainder to determine if it is odd or even; an even number will not have a reaminder in this case
rem = value % 2;
if (rem == 0){
printf("You've entered a even number. Please try again.\n");
return (0);
}
//greater than 9 cnd
if (value > 9){
printf("You have entered a number greater than 9. Please try again.\n");
return (0);
}
//less than 1 cnd
if (value < 1){
printf("You have entered a number less than 1. Please try again.\n");
return (0);
}
return (1);
}
int get_input()
{
int cont, number, valid;
cont = 1;
while (cont = 1)
{
printf("Enter an odd number less than 9 and greater than 0 < ");
scanf("%d", &number);
valid = is_valid(number);
if (valid == 1)
{
cont = 0;
}
}
return number;
}
}
You seem to have nested functions; this is (a) a non-standard GCC extension, and (b) I presume the scope of the nested get_input() function is the enclosing function, not the file scope. The solution is to move get_input() to file scope. At the end of print_pattern() add an extra }, and delete the final } at the end of the file.
Also, please format your code - most IDEs these days have options to tidy it up, and with correct indentation you may have seen your problem earlier.
Oh, and as a bonus bug fix, you also have in get_input():
while (cont = 1)
This will always be true - use this instead:
while (cont == 1)
The function print_pattern is not terminated at proper place but instead at the very end of the file:
void print_pattern(int size){
...
... end of the loop
}
... more functions
...
... end of print_pattern
}
This results into defining nested functions instead of global level.
It's generally good habit to indent the blocks, in which case you would realized the mistake very quickly.

Finding the largest even digit in a given integer

I am taking an online C class, but the professor refuses to answer emails and I needed some help.
Anyways, our assignment was to write a program that takes an integer from the user and find the largest even digit and how many times the digit occurs in the given integer.
#include <stdio.h>
void extract(int);
void menu(void);
int main() {
menu();
}
void menu() {
int userOption;
int myValue;
int extractDigit;
do {
printf("\nMENU"
"\n1. Test the function"
"\n2. Quit");
scanf("%d", &userOption);
switch (userOption) {
case 1:
printf("Please enter an int: ");
scanf("%d", &myValue);
extractDigit = digitExtract(myValue);
break;
case 2:
printf("\nExiting . . . ");
break;
default:
printf("\nPlease enter a valid option!");
}
} while (userOption != 2);
}
void digitExtract(int userValue) {
int tempValue;
int x;
int myArr[10] = { 0 };
tempValue = (userValue < 0) ? -userValue : userValue;
do {
myArr[tempValue % 10]++;
tempValue /= 10;
} while (tempValue != 0);
printf("\nFor %d:\n", userValue);
for (x = 0; x < 10; x++) {
printf("\n%d occurence(s) of %d",myArr[x], x);
}
}
I have gotten the program to display both odd & even digit and it's occurrences.
The only part that I am stuck on is having the program to display ONLY the largest even digit and it's occurrence. Everything I've tried has either broken the program's logic or produces some weird output.
Any hints or ideas on how I should proceed?
Thanks ahead of time.
Run a loop from the largest even digit to smallest even digit.
for (x = 8; x >=0; x-=2)
{
if(myArr[x]>0) //if myArr[x]=0 then x does not exist
{
printf("%d occurs %d times",x,myArr[x]);
break; //we have found our maximum even digit. No need to proceed further
}
}
Note:To optimize you should count and store occurrences of only even digits.
Why do you even use the extra loop? To find the largest even digit in an integer and the number of its occurences, a modification to the first loop would suffice.
Consider the following (untested, but I hope you get the idea):
int tempValue;
int x;
int myArr[10] = { 0 };
int maxNum = 0;
tempValue = (userValue < 0) ? -userValue : userValue;
do {
int currNum = tempValue % 10;
myArr[currNum]++;
tempValue /= 10;
if (currNum % 2 == 0 && currNum > maxNum)
maxNum = currNum;
} while (tempValue != 0);
After this, maxNum should contain the largest even digit, and myArr[maxNum] should be the number of its occurences.

srand() in dice game [duplicate]

This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 8 years ago.
I've been searching the site for possible answers to this problem, and although they're all similar they don't seem to be the exact same problem that I have, which is why I've been forced to open this question. SO I need to make a dice game that is supposed to roll 2 dice ranged from 1-6 and the user is supposed to guess what the number will be. The program then outputs the values of the die and reroll's if the guessed value isn't the real value of the 2 die. If it is then the program stops rolling the die and tells you how many rolls it took for the die to reach your guessed value.
For some reason my program keeps rolling the die over and over without stopping and I'm not exactly sure why. I tried testing it in a seperate program and have gotten even more confused as to why I still can't get different values even with srand() being called only once at the beginning of main.(I realized that, among a few other problems were what was wrong with the functions throwCalc1 and the unnecessary throwCalc2) If I try to place rand() outside a variable, I get different values, but if I put it within a variable the values stay the same. I've tried making the variable a function and it still doesn't work as the compiler gives me an error saying "initialization makes pointer from integer without a cast"
test function:
int main(void)
{
srand(time(NULL));
int i;
int *throwCalc = rand() % 6 + 1;
for(i = 0; i < 6; i++) {
printf("value is: %d\n", *throwCalc);
}
return 0;
}
original program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define _CRT_SECURE_NO_WARNINGS
#define MIN 2
#define MAX 12
int getInt(int min, int max) {
int retry = 1;
int value;
char after;
int cc;
do {
printf("Enter total sought \n"
"Range must be within [%d - %d]", min, max);
cc = scanf("%d%c", &value, &after);
if(cc == 0) {
printf("bad char or 0 input, please re-enter input");
clear();
} else if (after != '\n') {
printf("Error:Trailing characters, please re-ente input");
clear();
} else if (value < min || value > max) {
printf("Error: value outside of range, please re-enter input");
clear();
} else {
retry = 0;
}
} while(retry == 1);
return value;
}
void clear() {
while (getchar() != '\n') {
; //intentional empty statement
}
}
int throwCalc1() {
int a = 1, b = 6, n;
srand(time(NULL));
n = a + rand() % (b + 1 - a);
return n;
}
int throwCalc2() {
int a = 1, b = 6, n;
srand(time(NULL));
n = a + rand() % (b + 1 - a);
return n;
}
int throwResult(int input, int getcalc1, int getcalc2) {
int i = 0;
do {
throwCalc1();
throwCalc2();
printf("Result of throw %d : %d + %d", i, getcalc1, getcalc2);
i++;
} while(input != getcalc1 + getcalc2);
printf("You got your total in %d throws!\n", i);
return 0;
}
int main(void)
{
int input = getInt(MIN, MAX);
int getCalc1 = throwCalc1();
int getCalc2 = throwCalc2();
printf("Game of Dice\n");
printf("============\n");
printf("hi number is: %d", input);
throwResult(input, getCalc1, getCalc2);
return 0;
}
You do this once at the top of main:
int getCalc1 = throwCalc1();
int getCalc2 = throwCalc2();
And then expect the values to update just by calling throwCalc1() & 2 again.
Besides fixing srand(), have throwCalc1 & 2 return values into local variables instead of passing something in.
Right now you are calling throwCalc1() and throwCalc2() within your loop, but throwing away the results. You need to save those results in a pair of variables:
do {
getcalc1 = throwCalc1();
getcalc2 = throwCalc2();
printf("Result of throw %d : %d + %d", i, getcalc1, getcalc2);
i++;
} while(input != getcalc1 + getcalc2);
After you've done this, you might notice that getcalc and getcalc2 don't need to be parameters to that function - they can just be local variables within throwResult().
In addition, your throwCalc1() and throwCalc2() functions are identical, so you can remove one them and just call the remaining one twice.
Your test function should look like:
int main(void)
{
srand(time(NULL));
int i;
int throwCalc;
for(i = 0; i < 6; i++) {
throwCalc = rand() % 6 + 1;
printf("value is: %d\n", throwCalc);
}
return 0;
}

Resources