This question already has answers here:
Why has this function no effect when called?
(3 answers)
Closed 3 months ago.
#include <stdio.h>
#include <stdbool.h>
#include "header.h"
int main() {
bool check = true;
while (check) {
test(check);
//printf("%d", check);
}
return 0;
}
this is my main.c file
and this is my header.c file
#include <stdbool.h>
void test(bool check)
{
while (true)
{
if(check){
check = false;
break;
}
}
}
i notice this while im doing the another programm , and it goes inifite loop.
why the check value doesnt change to false?
get a false value and end loop
C is pass-by-value, not by-reference.
This means that test() gets a copy of the value of the check variable's value. It has no way to reach back and change the caller's variable, that the argument is named the same as the variable does not matter.
To fix it, you need to pass the address of the value instead, using pointers:
void test(bool *check)
{
while (true)
{
if (*check){
*check = false;
break;
}
}
}
and then of course you need to explicitly pass the address, in main():
int main() {
bool check = true;
while (check) {
test(&check);
//printf("%d", check);
}
return 0;
}
Of course, it would be cleaner to return the new value, instead of passing the pointer.
Related
so I'm trying to build an ATM program, and I can't really understand why my code isn't working.
code:
#include <stdio.h>
#include <stdbool.h>
bool accessCheck(int);
const int pin =1234;
int main(){
int code, access;
printf("Hi, please enter your password:");
scanf("%d",&code);
accessCheck(code);
if(accessCheck(code)==1){
printf("Password recognized.");
}
else {
printf("Password unrecognized.");
}
return 0;
}
bool accessCheck(int x){
bool access=0;
if(x == pin){
bool access = 1;
}
return access;
}
You're declaring new variable access inside the if block. This shadows the variable with the same name in the main block of accessCheck.
You should just assign that variable rather than declaring another variable.
#include <stdio.h>
#include <stdbool.h>
bool accessCheck(int);
const int pin =1234;
int main(){
int code;
printf("Hi, please enter your password:");
scanf("%d",&code);
if(accessCheck(code)){
printf("Password recognized.");
}
else {
printf("Password unrecognized.");
}
return 0;
}
bool accessCheck(int x){
bool access=false;
if(x == pin){
access = true;
}
return access;
}
Since you're using stdbool you can use true and false instead of 1 and 0.
There's no need to call accessCheck() before the if statement.
Using C, I want to run one function based on another. I need to check if a specific function is executed. if yes, then I want this function to execute as well when called, otherwise not.
I am reading some text from a file. in the first function, I want to read them and print them. now in the second function, I need a condition, that if the first function is executed, then run this as well. otherwise, do nothing.
How can I do that?
EDIT
NOTE: THIS IS THE COMPLETE SOLUTION. AFTER THE QUESTION WAS ANSWERED.
My code is here:
#include <stdio.h>
static int already_run = 0;
void Reading_Function(FILE **rf)
{
already_run = 1;
*rf=fopen("file.txt","r");
if(rf==NULL)
{
printf("Error in file openning.");
return 0;
}
char first [120];
fscanf(*rf,"%s",first);
printf("Value: %s", first);
}
// this is the second function
void Second_Function(FILE *rf)
{
if (already_run)
{
char second [50];
fscanf(rf,"%s",second);
printf("Value: %s", second);
}
else
return;
}
int main()
{
char t;
FILE *rf;
while(scanf("%c", &t)==1)
{
switch(t)
{
case 'f' :
Reading_Function(&rf);
break;
case 's' :
Second_Function(rf);
break;
}
}
return 0;
}
Let me know if the question is not clear. Thanks.
The comments above already answer your question. Just to keep things simple, here is what the code would look like:
static int already_run = 0;
void Reading_Function(FILE *rf) {
already_run = 1;
// ...
}
void Second_Function(FILE *rf) {
if (already_run) {
// ...
} else {
// ...
}
}
That said, if what you're trying to do is only have people call Second_Function but have the stuff in First_Function run the first time Second_Function is called, a better way to do this is:
void Second_Function(FILE *rf) {
static int already_run = 0;
if (!already_run) {
already_run = 1;
// Initialization code goes here. You can even split it out
// into a second function if you want, in which case you would
// just invoke that function here.
}
// ...
}
That way you don't have any global variables to worry about.
Of course, both methods break down if your code is multi-threaded; in that case, you should use a once (like pthread_once_t, call_once, InitOnceExecuteOnce, or something which abstracts the different APIs away for portability).
This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 5 years ago.
I'm creating a program that convert a binary number to a hexadecimal one.
This is my function
int cnt(int num)
{
int cn=0;
while (num!=0)
{
cn++;
num=num/10;
}
return cn;
}
int bintodec(int bin)
{
int cn=cnt(bin),result,a=1,i;
int A=0;
for (i=1;i<=cn;i++)
{
A=A+(bin%10)*(a);
a=a*2;bin=bin/10;
}
return A;
}
int *dectohex(int dec)
{
int cn=cnt(dec),i;
int A[cn];
for (i=1;i<=cn;i++)
{
A[cn-i]=dec%16;
dec=dec/16;
}
return A;
}
This is my caller:
int main()
{
int i,x;
printf("x = ");scanf("%d",&x);
for (i=1;i<=5;i++)
{
if (dectohex(x)[i]<10)
{
printf("\t%d",dectohex(x)[i]);
}
else if (dectohex(x)[i]==10)
{
printf("\tA");
}
else if (dectohex(x)[i]==11)
{
printf("\tB");
}
else if (dectohex(x)[i]==12)
{
printf("\tC");
}
else if (dectohex(x)[i]==13)
{
printf("\tD");
}
else if (dectohex(x)[i]==14)
{
printf("\tE");
}
else if (dectohex(x)[i]==15)
{
printf("\tF");
}
}
return 0;
}
It worked well together in an empty file, no error when built, and it printed correct results. But just when I add them to my project, errors appear everywhere I called the function dectohex() like in this image building logs. Did I do something wrong???
Your function does not return an array . It returns a pointer. The pointer points into an array which stops existing when the function returns. When you try to read through the pointer in the calling code, this causes undefined behaviour.
You need to fix your code so that you do not try to access arrays after they have been destroyed.
I'm trying to make a game that requires dynamically sized arrays in C but my code isn't working even though identical code works in another one of my programs.
Here are my #includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SwinGame.h" //API for graphics, physics etc
#include <math.h>
Here are my typedefs for the relevant structs used:
typedef struct position_data
{
double x;
double y;
} position_data;
typedef enum enemy_type_data {CIRCLE, TRIANGLE, SQUARE} enemy_type_data;
typedef struct enemy_data
{
position_data location;
enemy_type_data type;
bitmap bmp;
double health;
double speed;
int path_to;
} enemy_data;
typedef struct enemy_data_array
{
int size;
enemy_data *data;
} enemy_data_array;
Here is the function to add an element to the array:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
enemies->size++;
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
if (new_array) //if realloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
And here is my function call and variable declaration in the main procedure:
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
add_enemy(&enemies);
}
Why isn't this working?
You invoked undefined behavior by passing indeterminate value enemies->data in uninitialized variable having automatic storage duration. Initialize it before using add_enemy().
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
enemies.data = 0; /* add this line */
add_enemy(&enemies);
}
0 is a null pointer constant and can safely be converted to pointer NULL. Unlike NULL, 0 will work without including any headers. Of course you can use enemies.data = NULL; with proper header included.
#2501's explanation is completely correct. Another solution is to change your implementation of add_enemy() to something like this:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
// check if size was non-zero
if (enemies->size++)
{
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
}
// start new allocation
else
{
new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size);
}
if (new_array) //if (re)alloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
If fails because you haven't cleared the content of "enemies". Since it is a stack variable, it will contain whatever garbage data is on the stack.
set enemies.data to NULL in the main function and try it again.
This question already has answers here:
How to compare pointer to strings in C
(3 answers)
Closed 8 years ago.
I try to make a clipboard logger. The idea is that every 5 seconds the program checks of the text on the clipboard is changed; but the problem is that at the beginning the clipboard is shown twice, and after that is shows nothing.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <windows.h>
DWORD WINAPI check()
{
char *strData;
char *oldData = "";
for(;;){
OpenClipboard(NULL);
HANDLE hClipboardData = GetClipboardData(CF_TEXT);
char *pchData = (char*)GlobalLock(hClipboardData);
strData = pchData;
GlobalUnlock(hClipboardData);
CloseClipboard();
if(strData == oldData)
{
//do nothing
}
else
{
printf("%s\n", strData); //here its print twice and then nothing what is not the intention
oldData = strData;
}
Sleep(5000);
}
}
int main()
{
printf("Hello\n");
printf("Your clipboard:\n");
HANDLE thread = CreateThread(NULL, 0, check, NULL, 0, NULL);
getchar();
return 0;
}
Can someone help me?
You have several problems...
If you want to keep a string you need to have it static, otherwise the variable is lost at the time you return from that function.
DWORD WINAPI check()
{
char *strData;
static char *oldData = NULL; // here you'd need static and use NULL by default
As mentioned by others, comparing strings is done with strcmp() or alike:
if(strcmp(strData, oldData) == 0)
However, now that oldData can be NULL you must verify that it is allocated:
if(oldData && strcmp(strData, oldData) == 0)
If a new string is given, then you want to free the old one and replace with the new one:
if(oldData) free(oldData);
oldData = strdup(strData);
Now it should work.