Here is my code:
#define MAX_SET_LENGTH 255
typedef struct{
char name;
char *elemetns;
}Set;
void createSet();
int getString();
void filter(char raw[],int *length);
void menu();
void del_duplicate(char *s,int n);
void displyAllSets();
Set sets[26];
int setCount=0;
int main(){
menu();
}
void menu(){
int input;
do{
printf("\n1.Create Set.\n");
printf("2.display all Sets.\n");
printf("0.Exit.\n");
scanf("%d",&input);
switch(input){
case 0:
break;
case 1:
createSet();
break;
case 2:
displyAllSets();
break;
default:
printf("Error input,please input again\n");
}
}while (input!=0);
}
void displyAllSets(){
int i;
for(i=0; i<setCount; i++) {
printf("\n%c->{%s}\n",sets[i].name,sets[i].elemetns);
}
}
void createSet(){
if(setCount<26){
printf("Please input the set's elements:\n");
char elements[MAX_SET_LENGTH];
int s_length = getString(elements,MAX_SET_LENGTH);
filter(elements,&s_length);
del_duplicate(elements,s_length);
if(s_length > 0){
elements[s_length]='\0';
Set set;
set.elemetns = elements;
set.name = 'a'+ setCount;
sets[setCount++]=set;
displyAllSets();
}else{
printf("No illegal input!\n");
}
}else{
printf("It's limit to 26");
}
}
int getString(char s[],int max_length){
char c;
int i=0;
getchar();
while((c=getchar())!='\n')
s[i++]=c;
return (i>=max_length ? max_length : i);
}
void filter(char raw[],int *length){
char string[*length];
int i=0,j=0;
int deletedCount=0;
for(;i<*length;i++){
string[i]=raw[i];
}
for(i=0;i<*length;i++){
if(string[i]>='A' && string[i]<='Z'){
raw[j++]=string[i];
}else{
deletedCount++;
}
}
*length-=deletedCount;
raw[j]='\0';
}
void del_duplicate(char raw[],int length){
int i=0,j;
for(;i<length && length>0;i++){
for(j=i+1;j<length;){
if(raw[i]==raw[j]){
int delFrom=j;
while(delFrom<length){
raw[delFrom]=raw[delFrom+1];
delFrom++;
}
j=i+1;
length--;
}else{
j++;
}
}
}
}
Everything looks good when calling createSet();
but, after calling printf("\n1.Create Set.\n") in do-while block, the array sets has been modified. Can anyone help?
after pressing F6
Can you see that left bottom window, sets[0].elements gets changed, what's happening?
You are storing the address of a local variable on this line:
set.elemetns = elements;
That is undefined behaviour. Don't do it!
If you want to copy the string, do one of the following:
Change the structure to store a char array and use strncpy to copy the string; or
Duplicate the string (and remember to free it later): set.elemetns = strdup(elements);
In a completely separate issue, you have implemented a function getString that seems to do roughly what fgets does. You should use fgets instead.
Related
This code has several issues that are beyond my understanding.
First, no matter how hard I try, the variable ok doesn't get saved in the file, thus ruining the display. It is strange because other variables work, it is just that one that doesn't seem to be working, even if I change the order.
Also, the delete and modify functions aren't working, as well.
I tried everything, but nothing seems to be working.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
// Structure of the employee
struct emp {
char name[50];
char ok[50];
int hr;
int age;
int id;
};
FILE *f;
emp* add(emp *e,int n){
int i;
char p;
emp *t;
int k;
t=(emp*)malloc(n*sizeof(int));
f=fopen("Data.txt","w");
for(i=0;i<n;i++){
printf("\nEnter Name : ");
scanf("%s",(t+i)->name);
printf("\nEnter Departement: ");
scanf("%s",&(t+i)->ok);
printf("\nEnter Age : ");
scanf("%d",&(t+i)->age);
printf("\nEnter avearge hour of works(per week) : ");
scanf("%d",&(t+i)->hr);
// k = ( ( (t+i)->hr ) *40 );//40 is minimum wage for each hour of work
// printf("Salary of The employe: %d\n",k);
printf("\nEnter EMP-ID : ");
scanf("%d",&(t+i)->id);
fprintf(f,"%s\n%s\n%d\n%d\n%d\n",(t+i)->name,(t+i)->ok,(t+i)->age,(t+i)->hr,(t+i)->id);
}
fclose(f);
return t;
}
void aff(emp *t,int n){
int I;
f=fopen("Data.txt","r");
for(i=0;i<n;i++){
if (f != NULL){
fscanf(f,"%s",&(t+i)->name);
fscanf(f,"%s",&(t+i)->ok);
fscanf(f,"%d",&(t+i)->age);
fscanf(f,"%d",&(t+i)->hr);
fscanf(f,"%d",&(t+i)->id);
printf("Name : %s\n",(t+i)->name);
printf("departement : %s\n",(t+i)->ok);
printf("Age : %d\n",(t+i)->age);
printf("Hours : %d\n",(t+i)->hr);
printf("ID : %d\n",(t+i)->id);
}
}
fclose(f);
}
//emp* modf(emp *t,int n){
// int i;
// int k;
// char nv[50];
// printf("id of the entry you want to be modified" );
// scanf("%d\n",&k);
// for(i=0;i<n;i++){
// if(k==(t+i)->id){
// scanf("%s",&nv);
// (t+i)->name=nv;
// }
// }
// return t;
//}
//void del(emp *t,int n){
// int i;
// emp a;
// int k;
// printf("position of the entry you want to delete?");
// scanf("%d",&a);
// for(i=0;i<n;i++){
// if (a == *(t+i)) {
// for(i=k;i<n-1;i++){
// *(t+i)=*(t+i+1);
// }
// }
// }
//}
int main(int argc, char *argv[]){
int c;
emp e;
emp *k;
k=&e;
int n;
emp *t;
t=&e;
char p;
ka:
printf("Welcome To The employe management Menu\n");
printf("1.Add employes?\n");
printf("2.show all employes?\n");
printf("3.delete an entry?\n");
scanf("%d",&c);
switch (c){
case 1:
ed:
printf("How many employes you want to add?\n");
scanf("%d",&n);
add(k,n);
if(p=='y'){
goto ed;
}
else goto ka;
break;
case 2:
aff(t,n);
break;
case 3:
del(t,n);
break;
}
return 0;
}
At least these issues:
Wrong allocation size #Weather Vane
Avoid allocation errors. Allocate to the size of the refenced object, not the type.
// t=(emp*)malloc(n*sizeof(int));
t = malloc(sizeof t[0] * n);
Easier to code right, review and maintain.
Uninitialized p #Craig Estey
f(p=='y') is undefined behavior as p is uninitialized.
This hints that OP is not compiling with all warnings enabled. Save time - enable all warnings.
emp not defined
Perhaps OP is not using a C compiler, but a C++ one?
i not defined in for (i = 0; i < n; i++) {
Is int I; the true code?
Bad "%s"
Without a width, "%s" is worse than gets(). Use a width like "%49s".
I have to create a program that has an array of costumers (structs that contain name, code and documentation) and functions to insert, remove and list all of them in order of code. I'm not understanding what I should do. Please note that the parameters for insertCostumer, removeCostumer and listCostumer cannot be changed.
Piece of code 01:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define MAX_REG 10
typedef struct _costumer {
int code;
char name[50];
char documentation[20];
} costumer;
Piece of code 02:
int main(int argc, char** argv) {
costumer *costumers[MAX_REG];
costumer **p_costumer;
p_costumer = &costumers[0];
int count = 0;
memset(costumers, 0, sizeof(costumers));
//Some code to check what to do using a switch
case '1': insertCostumer(p_costumer, &count); getch(); break;
case '2': removeCostumer(p_costumer, &count); getch(); break;
case '3': listCostumers(p_costumer, &count); getch(); break;
//Some code
return (EXIT_SUCCESS);
}
Piece of code 03:
void insertCostumer(costumer **p_costumer, int *count){
char aux[50];
char aux2[20];
if(*count < MAX_REG) {
*p_costumer = (costumer *) malloc(sizeof(costumer));
printf("\nInsert the code: ");
gets(aux);
(*p_costumer)->code = atoi(aux);
printf("Insert the name: ");
gets(aux);
strcpy((*p_costumer)->name, aux);
printf("Insert the documentation: ");
gets(aux2);
strcpy((*p_costumer)->documentation, aux2);
(*count)++;
p_costumer = &*p_costumer[*count];
} else {
printf("List full! Remove a costumer first!\n");
}
}
void removeCostumer(costumer **p_costumer, int *count){
char aux3[50];
int cod;
printf("\nInsert the code of the costumer to be removed: ");
gets(aux3);
cod = atoi(aux3);
for(int i = 0; i < *count; i++) {
if(p_costumer[i]->code == cod) {
strcpy(p_costumer[i]->name, NULL);
p_costumer[i]->code = 0;
strcpy(p_costumer[i]->documentation, NULL);
}
}
}
void listCostumers(costumer **p_costumer, int *count){
for(int i = 0; i < *count; i++) {
printf("Code: %d | Name: %s | Documentation: %s\n", p_costumer[i]->code, p_costumer[i]->name, p_costumer[i]->documentation);
}
}
I don't know what I'm doing wrong; nothing is working, honestly. I was trying to first insert, list and remove to try and make the sorting part later, but I can't even get this part done. When I list, only the last costumer added is listed, for example.
Can someone help me?
Okay, I had to refactor a considerable amount of your code, so I don't have a blow by blow description of the changes.
You'll just have to study it a bit.
Note that even if you're passed a double pointer as an argument, doesn't mean you have to use it as a double in the body of the functions. Note, in particular, what I did for the count (e.g. int count = *p_count; and *p_count = count;)
But, it should be noted that the list is one of pointers to structs and not merely a pointer to an array of structs (i.e. there is an extra level of indirection). This makes things a bit faster.
Note that, bug fixes aside, the key is the "slide" operation in the remove function.
Because we're "sliding" pointers, this is faster/more efficient with the pointer array. Study this [concept] well.
Never use gets--always use fgets
I've deliberately left off comments. This will allow you to add them as you analyze the code. I've found that this can be a powerful technique for understanding a [foreign] code base.
Anyway, here's the code. I've done some rudimentary testing and it seems to work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <conio.h>
#define MAX_REG 10
char aux[1000];
typedef struct _costumer {
int code;
char name[50];
char documentation[20];
} costumer;
void
lineget(char *buf,size_t buflen)
{
char *cp;
cp = fgets(buf,buflen,stdin);
if (cp != NULL) {
cp = strrchr(buf,'\n');
if (cp != NULL)
*cp = 0;
}
}
void
insertCostumer(costumer **p_costumer, int *p_count)
{
costumer *add;
int count = *p_count;
char aux2[20];
if (count < MAX_REG) {
add = malloc(sizeof(costumer));
printf("\nInsert the code: ");
lineget(aux,sizeof(aux));
add->code = atoi(aux);
printf("Insert the name: ");
lineget(add->name,sizeof(add->name));
printf("Insert the documentation: ");
lineget(add->documentation,sizeof(add->documentation));
p_costumer[count] = add;
++count;
}
else {
printf("List full! Remove a costumer first!\n");
}
*p_count = count;
}
void
removeCostumer(costumer **p_costumer, int *p_count)
{
int count = *p_count;
int cod;
int i;
costumer *cur;
printf("\nInsert the code of the costumer to be removed: ");
fgets(aux,sizeof(aux),stdin);
cod = atoi(aux);
int slide = 0;
for (i = 0; i < count; i++) {
cur = p_costumer[i];
if (cur->code == cod) {
slide = 1;
break;
}
}
if (slide) {
free(cur);
--count;
for (; i < count; ++i)
p_costumer[i] = p_costumer[i + 1];
p_costumer[count] = NULL;
}
*p_count = count;
}
void
listCostumers(costumer **p_costumer, int *p_count)
{
costumer *cur;
int count = *p_count;
for (int i = 0; i < count; ++i, ++cur) {
cur = p_costumer[i];
printf("Code: %d | Name: %s | Documentation: %s\n",
cur->code, cur->name, cur->documentation);
}
}
int
main(int argc, char **argv)
{
costumer *costumers[MAX_REG];
costumer **p_costumer;
char buf[100];
p_costumer = &costumers[0];
int count = 0;
memset(costumers, 0, sizeof(costumers));
setbuf(stdout,NULL);
//Some code to check what to do using a switch
while (1) {
printf("operation to perform (1=insert, 2=remove, 3=print): ");
char *cp = fgets(buf,sizeof(buf),stdin);
if (cp == NULL)
break;
switch (cp[0]) {
case '1':
insertCostumer(p_costumer, &count);
break;
case '2':
removeCostumer(p_costumer, &count);
break;
case '3':
listCostumers(p_costumer, &count);
break;
}
}
return (EXIT_SUCCESS);
}
I created the following code, it compiles but it doesen't run properly. It shows some imput witch is correct, but after that, instead of printing according to the line printf(prod[0].dr[0]); it enters an "not responding" state. If you instead write printf(prod[0].dr); it works perfectly. I need to be able to print each character individualy (so I need something like printf(prod[0].dr[0]); that works)
If the question is to broad, please comment and I will try to specify every detail.
Thanks!
#include <stdio.h>
FILE *f, *g;
struct productie
{
char st, dr[20];
int realizabil;
}prod[30];
int citire(FILE *f){
char sir[100];
int i=0,j;
while(!feof(f))
{
fgets(sir,100,f);
prod[i].st=sir[0];
for(j=3;j<strlen(sir);j++)
prod[i].dr[j-3]=sir[j];
i++;
}
return i;
}
int exista(char sir[],char c)
{
int i;
for(i=0;i<strlen(sir);i++)
{
if(c==sir[i])
return 1;
}
return 0;
}
void neterminale(struct productie p[],int n, char N[])
{
int k=0;
int i,j;
for(i=0;i<n;i++)
{
if(isupper(p[i].st) && !exista(N,p[i].st))
N[k++]=p[i].st;
for(j=0;j<strlen(p[i].dr);j++)
if(isupper(p[i].dr[j]) && !exista(N,p[i].dr[j]))
N[k++]=p[i].dr[j];
}
N[k]='\0';
}
void terminale(struct productie p[],int n, char T[],char N[])
{
int k=0;
int i,j;
for(i=0;i<n;i++)
{
if(!exista(N,p[i].st) && !exista(T,p[i].st)&& p[i].st!='$')
T[k++]=p[i].st;
for(j=0;j<strlen(p[i].dr);j++)
if(!exista(N,p[i].dr[j]) && !exista(T,p[i].dr[j]) && p[i].dr[j]!='$')
T[k++] = p[i].dr[j];
}
T[k]='\0';
}
void afisare(FILE *g,int n){
int i;
for(i=0;i<n;i++)
fprintf(g,"%c -> %s",prod[i].st, prod[i].dr);
}
int main(){
char N[30];
char T[30];
int i,j,n;
f=fopen("in.txt","r");
n=citire(f);
neterminale(prod,n,N);
printf("\nNeterminalele sunt:{");
for(i=0;i<strlen(N);i++)
printf("%c ",N[i]);
printf("}");
terminale(prod,n,T,N);
printf("\nTerminalele sunt:{");
for(i=0;i<strlen(T);i++)
{
printf(" %c ",T[i]);
}
printf("}");
printf(prod[0].dr[0]); //AT THIS LINE IS THE PROBLEM
g=fopen("out.txt","w");
afisare(g,n);
fclose(f);
fclose(g);
return 0;
}
The in.txt :
S->aS
S->a
S->$
S->AB
A->b
B->c
If you want to print a string directly, you need to provide a pointer to the first character, not the first character itself:
printf(&(prod[0].dr[0]));
or
printf(prod[0].dr);
But you can't limit this to a single char (there is no nprintf function).
I am trying to create a simple program where the idea of the task is to create a stack that can take in a set number of values for the array and be able to push and pop the values on command. I am having trouble getting to my pass around correctly. I do not think the values are even getting added to the array.
#include <stdio.h>
#include <stdlib.h>
int push(int x, int st, int stack1[]);
int pop(int st, int stack1[]);
int main ()
{
char stack1[10];
int stmax = 5;
int st = -1;
int x;
int choice;
while (1) {
printf("What would you like to do? \n1. Check Empty\n2. Check Full\n3. Push\n4. Pop\n5. show\n\n");
scanf("%d", &choice);
switch (choice) {
case 1:
if(st = -1){
printf("Empty\n");
} else {
printf("Not Full\n");
}
break;
case 2:
if(st == stmax) {
printf("Full\n");
} else {
printf("Not Full\n");
}
break;
case 3:
printf("Enter a int to add to the stack:\n");
scanf("%d", &x);
push(x, st, stack1);
break;
case 4:
pop(st, stack1);
printf("%d", stack1[st]);
default:
break;
}
} return(0);
}
int pop(int st, int stack1[]) {
int data;
data = stack1[st];
printf("%d", data);
return(st);
}
int push(int x, int st, int stack1[]) {
st ++;
stack1[st]=x;
return(st);
}
I am trying to implement a program using stacks.But the stack is not getting displayed
#include<stdio.h>
int size=0,count=1,test=0;
struct Car
{
int registrationNo;
char *name;
};
struct ParkingLot
{
struct Car C[10];
};
struct stack
{
struct ParkingLot P;
int top;
} st;
int stfull()
{
if(st.top >= size-1)
return 1;
else
return 0;
}
void push(struct Car item) {
st.top++;
st.P.C[st.top] = item;
}
int stempty() {
if (st.top == -1)
return 1;
else
return 0;
}
void display() {
int i;
if (stempty())
printf("\nStack Is Empty!");
else {
//printf("%d\n",st.top);
for (i = 0; i<=st.top; i++)
printf("\n%s", st.P.C[i].name);
}
}
void Enter_ParkingLot()
{
struct Car CC;
int checkFull=stfull();
if(checkFull==1)
printf("Parking Lot is FUll\n");
else
{
CC.registrationNo=count;count++;
char ch[100];
printf("Enter name of owner\n");
scanf("%s",ch);
CC.name=ch;
push(CC);
}
}
int main()
{
printf("Enter size of Parking Lot\n");
st.top=-1;
scanf("%d",&size);
Enter_ParkingLot();
Enter_ParkingLot();
display();
return 0;
}
This was my input on terminal-
Enter size of Parking Lot
2
Enter name of owner
ABCD
Enter name of owner
EFGH
This was my output-
`#
`#
There was a blank line before first # in the output.
If you assign the pointer field in struct Car to a local variable, it will not work, you need to redeclare your struct Car like this
struct Car
{
int registrationNo;
char name[100];
};
and then instead of
CC.name=ch;
do it this way
strcpy(CC.name, ch);
also, it's better to write
scanf("%99s",ch);
to prevent overflowing ch, and in your case it would be even better to do
scanf("%99s", CC.name);
I fixed your code
#include <stdio.h>
#include <string.h>
struct Car
{
int registrationNo;
char name[100];
};
struct ParkingLot
{
struct Car C[10];
};
struct stack
{
struct ParkingLot P;
int top;
} st;
int stfull(int size)
{
if(st.top >= size - 1)
return 1;
return 0;
}
void push(struct Car item)
{
st.P.C[++(st.top)] = item;
}
int stempty()
{
if (st.top == -1)
return 1;
return 0;
}
void display()
{
int i;
if (stempty() != 0)
printf("\nStack Is Empty!");
else {
for (i = 0 ; i <= st.top ; i++)
printf("\n%s", st.P.C[i].name);
}
}
int Enter_ParkingLot(int count, int size)
{
struct Car CC;
if (stfull(size) == 1)
printf("Parking Lot is FUll\n");
else
{
CC.registrationNo = count;
printf("Enter name of owner\n");
scanf("%99s", CC.name);
push(CC);
}
return count + 1;
}
int main()
{
int size = 0, count = 1;
printf("Enter size of Parking Lot\n");
st.top = -1;
scanf("%d", &size);
count = Enter_ParkingLot(count, size);
count = Enter_ParkingLot(count, size);
display();
return 0;
}
I removed global variables, they where not needed.
I fixed some if/else's which made no sense.
I also applied my previously suggested fixes related to your original problem.
The Problem:
You store the name of the car into an array that is allocated on the stack.
You then copy the pointer to that array to your car object.
The original array then goes out of scope.
You then try to print that array, which no longer exists, via the pointer.
Undefined behavior occurs.
The Solution:
You need to allocate memory for the name of the car with malloc() and use strcpy() to copy it to the car object.