I am programming a simple text editor in C. I have to define inuse_head and free_head as global variables. I need to change the value of the 2 global variables in a function. Here is the code I wrote so far:
#include <stdio.h>
#include <string.h>
struct node
{
char statement[40];
int next;
};
struct node textbuffer[25];
int free_head;
int inuse_head;
void insert(int line, char* stat)
{
FILE *file;
file=fopen("deneme.txt","a");
if(file!=NULL)
{
int i;
int k;
strcpy(textbuffer[line].statement,stat);
textbuffer[line].next=line+1;
fprintf(file,textbuffer[line].statement);
for(i=0;i<=25;i++)
{
if(textbuffer[i].statement==NULL)
{
free_head=i;
break;
}
}
for(k=0;k<=25;k++)
{
if(textbuffer[k].statement!=NULL)
{
inuse_head=k;
break;
}
}
}
else
{
printf("File couldn't found.");
}
fclose(file);
}
int main()
{
insert(3,"Hello World");
printf("free list: %d and inuse list: %d",free_head,inuse_head);
return 0;
}
Now when I print free_head and inuse_head, it prints 0 for both of them. I need to change free_head's and inuse_head's values in function insert. I think I should handle it with pointers but how?
The reason why both variables have the value 0 is not that the function insert is having trouble accessing these variables. Since the variables are both global, the function insert can access both variables directly, like any other variable. It is therefore not necessary to use pointers for accessing these variables.
The problem is rather that in the function insert, the line
free_head=i;
never gets executed, and the line
inuse_head=k;
is only executed once, at a time when k has the value 0.
That is why both variable's values never change their values and both keep their initial value of 0 throughout the entire program.
Also, it is worth noting that your program has undefined behavior. As already pointed out in the comments section, you are accessing the array textbuffer out of bounds.
The line
for(i=0;i<=25;i++)
should be changed to
for(i=0;i<25;i++)
and the line
for(k=0;k<=25;k++)
should be changed to:
for(k=0;k<25;k++)
Related
I am writing a code in which the function "verif" is supposed to verify whether the characters differ in a string or not. This function is then called for each line in a file. However, although i verified and the function is ok, there is something i am doing wrong concerning the returning of pointers or the attribution in the main function. The result i get is 'null null null' for each line of the file ( my file has 3 lines)
This is my code:
#include <stdio.h>
#include <stdlib.h>
char* verif (char line[])
{
int i,j,ok=1;
char v[5];
for (i=0; i<strlen(line); i++)
{
for (j=i+1; j<strlen(line); j++)
{
if (line[i]==line[j])
{
ok=0;
break;
}
}
}
if (ok==0) strcpy(v,"No");
else strcpy(v,"Yes");
return v;
}
int main()
{
FILE *f;
char sir[30];
char* ctrl;
if ((f=fopen("fis.txt","r"))==NULL) exit(1);
while (fscanf(f,"%[^\n]",sir))
{
if (fgetc(f)==EOF) break;
puts(sir);
ctrl=verif(sir);
printf("%s",*ctrl);}
}
You are returning the address of a local variable from a function with your statement return v;
Your options:
Declare v as static, so that it goes into the process' data section, rather than on the local stack for the function.
Use the heap (malloc/free) to manage the string in v, since objects on the heap persist beyond the lifetime of the scope they are declared in if they are not freed.
#include <stdio.h>
#include <string.h>
void increase(char **tab)
{
int i=strlen(*tab);
int o=i;
while((*tab)[i]!='5' && i>=0)
{
i--;
}
if(i>=0)
{
int tt;
char array[o+1];
for(tt=0;tt<o;tt++)
{
if(tt!=i)
array[tt]=(*tab)[tt];
else
array[tt]='6';
}
array[o]='\0';
*tab=array;
// printf("\n%s",*tab);
}
else
{
char array[o+2];
int tt;
for(tt=0;tt<=o;tt++)
{
array[tt]='5';
}
array[o+1]='\0';
*tab=array;
// printf("\n%s",*tab);
}
}
int main()
{
int n;
char *test;
test="555";
increase(&test);
printf("\n%s",test);
return 0;
}
Okay, so increase() is meant to replace number in test with the next number containing only 5 and 6.
What I wanted to do is to change the value of test directly by using pointer to char*. Everything seems to work just fine untill it comes to displaying changed value - it simply won't show unless was asked to do it inside the
increase() function. Once I add
printf("\n%s",*tab);
inside any of conditions (commented), everything works just fine (excluding showing a double result).
What causes a problem here?
555 is just a testing value, actually any number made of 5s or 6s will do the work.
Lines like *tab=array; cause a problem, given that array is a local variable that goes out of scope when its enclosing block ends. In main(), test now points to memory that's invalid, and trying to use it is undefined behavior.
I'm trying to code a Turing machine in C.
But my program doesn't work, it gets stuck in an endless loop.
Here's my code with some explanations:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3 //number of different states for the cells
#define K 20 //length of the tape
typedef struct
{
int state;
int head;
char tape[];
}mt; //machine
void init_mt(mt* machine, char val[], int n)
{
machine->state=1; //edited mistake
machine->head=0; // edited mistake
int i;
for(i=0;i<n;i++)
{
machine->tape[i]=val[i];
}
}; //initialization of a machine
typedef struct
{
char write;
char direction;
int state;
}actions; //actions composed of three instructions
typedef struct
{
actions exec01;
actions exec02;
actions exec11;
actions exec12;
}program; //program composed of four actions
void execute(actions exec, mt mach)
{
mach.tape[mach.head] = exec.write;
mach.state = exec.state;
if(exec.direction == 'R')
{
mach.head++;
}
else
{
mach.head--;
}
} //class that follows the instructions from the actions
void execute2(mt mach, program p)
{ do{
printf("%c %d %d \n", mach.tape[mach.head], mach.head, mach.state );
if(mach.tape[mach.head] == 0)
{
if(mach.state == 1)
{
execute(p.exec01, mach);
}
else if(mach.state == 2)
{
execute(p.exec02,mach);
}
}
else if(mach.tape[mach.head] == 1)
{
if(mach.state == 1)
{
execute(p.exec11,mach);
}
else if(mach.state == 2)
{
execute(p.exec12,mach);
}
}
}while( (mach.head<K) && (mach.state != 3));
} // class that read the program and act according to the states of the cells,
//keeps going until the machine is at the third state or if it reaches the end of the tape
int main(){
mt machine;
char t[10]={'1','1','1','0','0','1','0','1','0','1'};
init_mt(&machine, t, 10);
program p ={ {'0','R',1}, {'0','R',1}, {'1','R',2}, {'0','L',3} };
execute2(machine, p);
return 0;
} //main with a tape composed of 10 cells and a program composed of four actions
This program keeps displaying "0,0,1" indefinitely and I can't find the error.
Thanks for the help and sorry if this unclear.
There are a few problems here:
In some instances you're passing your structures as arguments, rather than pointers to them. This creates local copies of the entire structures in the called function. Any changes made to those copies will be lost when the functions return. It is also inefficient. Just pass structure pointers.
You aren't declaring any space for tape in your structures, so it's basically a zero-length array. Any kind of access whatsoever will corrupt memory and result in undefined behavior. You have a couple choices here. You can either choose some fixed size for it, and use that for the array size, or you can change it to a pointer and dynamically allocate storage for it. One way or another, you have to allocate the storage.
In execute2, it's comparing mach.tape[mach.head] to the integers 0 and 1. But the tape doesn't contain those values. It contains the characters '0' and '1'. So surround those constants with single quotes. It would also be a good idea to print an error if an unexpected value is encountered. That would have caught this problem instantly.
In function execute, you pass the structure mach by value. In that function you also perform
mach.head++
This, value presumably should be given back to the function execute2. So you will have to pass the structure mach by reference to this function.
I do not understand why i have to initialize my structure before using it, i get this error in my code, i know it works if i use pointers or if i initialize the structure members, but why it does not work in this way ?
#include <stdio.h>
typedef struct human{
char name[20];
int age;
} student;
void function(student ){
printf("It's not working");
}
int main(){
student a;
function(a);
return 0;
}
I get this
Debug Error!
File: Run - Time Check Failure #3 - The variable 'a' is being used without being initialized. (Press Retry to debug the application)
and i do not get the message from my function on output
You get this error, because your debugger detect, that you are sending unitialized variable to the function. It doesn't know, what will you do with it inside of the function, so it warns you. You can see, that if you run program in release, no error will occur. Easiest solution for you, if you know, that you will initialize it lately to correct values, is just to initialize it, when creating student a = {0};
You are passing the object a by value to function. As C has only value-semantics, it can only copy values in this case. So, you initialise the parameter (even if your implementation doesn't care about the parameter) with an unitialised object, wich requires reading from that object. This is undefined behaviour, hence the compiler informs you that you are doing something illegal.
If you pass the object via a pointer, you still pass-by-value, but the value being copied is the pointer. Hence you don't have to read the actual value and your compiler wont complain.
Observe:
void flat(student s) {
s.age = 20;
}
void ptr(student* s) {
s->age = 20;
}
int main() {
student s = {"Eve", 0};
// { s.age == 0 }
flat(s);
// { s.age == 0 } --- still the same, no change
ptr(&s);
// { s.age == 20 } --- now it has changed
}
I am reading some data from file which are nested into each other (like a file tree) to put it into an array.
Reading is done well, but i am not able to put the array back into main(). The result of AnzGrid is 0, so the for-loop will not start.
Has anyone a hint for me how to do it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void read_include(int,int*,char*);
void read_include(int AnzGrid,int* GridIDs,char* Input){
char Line[81];
char* Token;
FILE * File;
FILE * File1;
File = fopen(Input,"r");
printf("opening %s\n",Input);
if (!File){
printf("%s not found here\n",Input);
return;
}
if (File){
while (fgets(Line,80,File)){
printf("%s",Line);
if (strncmp(Line,"GRID ",8) == 0){
Token=strtok(Line," ");
Token=strtok(NULL," ");
GridIDs[AnzGrid] =atoi(Token);
AnzGrid++;
}
if (strncmp(Line,"INCLUDE ",8) == 0){
Token=strtok(Line,"'");
Token=strtok(NULL,"'");
read_include(AnzGrid,GridIDs,Token);
}
}
fclose(File);
}
printf ("%i\n",AnzGrid);
return;
}
int main( int argc, char* argv[] ) {
char Input[81];
int i;
int AnzGrid;
int GridIDs[100];
strcpy(Input,argv[1]);
read_include(AnzGrid,GridIDs,Input);
printf ("=>%i\n",AnzGrid);
for (i=0;i<AnzGrid;i++){
printf ("GridID: %i\n",GridIDs[i]);
}
It's because when you pass arguments to functions they are passed by value, in other words the values of the arguments you pass are copied in the function. That also means that any changes you make to an argument inside a function are made on the copies, and those changes will be lost once the function returns.
There are basically two ways of solving this in C:
Return values from the function using return
Emulate pass by reference by passing a pointer to the data, and using the dereference operator inside the function.
The second alternative could require some example code:
/* Passing `AnzGrid` as a pointer */
void read_include(int *AnzGrid,int* GridIDs,char* Input){
...
(*AnzGrid)++; /* Using the dereference operator */
...
}
You call the function, not by declaring AnzGrid as a pointer, but by using the address-of operator:
int main(...) {
int AnzGrid = 0; /* Initialize */
...
read_include(&AnzGrid,GridIDs,Input); /* Note use of address-of operator `&` */
...
}
Note: In the snippet of code for the main function, I also fix another bug you have, one leading to undefined behavior: You not initializing the AnzGrid variable. Local variables are not automatically initialized, instead their values are indeterminate (and will be seemingly random). Using an uninitialized local variable without initializing it leads to the mentioned undefined behavior. For example, if AnzGrid have an indeterminate value, what would AnzGrid++ do and what would the result be?
Your read_include function should probably return a malloc-ed pointer to some struct containing the read data.
Of course you should adopt the convention that read_include is returning a heap allocated pointer, and free it later suitably.
BTW, you should compile your code with all warnings and debug info (e.g. with gcc -Wall -g if using GCC) and you should learn how to use the debugger (e.g. gdb)