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);
}
Related
....
1. I have started to learn C recently. I don't know what's wrong with my code. programs runs but it doesn't ask for user input. it just skip and store random value . Please help me to fix it [![Output][1]][1]
[1]: https://i.stack.imgur.com/RNnKY.png
1) This is my cmain.c file
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include "boolean.h"
#include "cstack.h"
cstack top;
char data_item[100];
int main(void)
{
init_cstack(&top);
boolean quit = FALSE;
boolean showmenu = TRUE;
int menu_sel;
while(!quit){
if(showmenu){
printf("\nEnter a selction\n");
printf("1 PUSH\n");
printf("2 POP\n");
printf("3 PRINT\n");
printf ("4 Quit\n");
scanf("%d",&menu_sel);
}
switch(menu_sel){
case 1:
if(!is_cfull()){
printf("\nEnter a character to push\n");
// fscanf("%c",&data_item);
scanf("%c",&data_item);
cpush(&top ,*data_item);
break;
}
else{
printf(" stack is full\n");
break;
}
case 2:
if(!is_cempty(top)){
printf("\nEnter a character to pop \n");
scanf("%c", &data_item);
printf("%s Was removed\n",data_item);
cpop(&top);
break;
}
else{
printf(" stack is empty\n");
break;
}
case 3:
if(!is_cempty(top)){
printf("\nList\n");
print_cstack(top);
break;
}
else{
printf(" stack is empty\n");
break;
}
case 4:
quit = TRUE;
break;
default: printf("%d is not a vaild menu selection\n",menu_sel);
}
}
return 0;
}
2)This is cstack.c file
#include <stdio.h>
#include <stdlib.h>
#include "boolean.h"
#include "cstack.h"
void init_cstack(cstack *s){
(*s) = NULL;
}
void cpush(cstack*s, char x){
cstack temp;
temp= (cstack)malloc(sizeof(struct cstacknode));
temp -> data = x;
temp -> next = (*s);
(*s) = temp;
}
char cpop(cstack *s){
cstack temp;
char data_popped;
temp = *s;
data_popped =temp->data;
*s =temp->next;
free(temp);
return data_popped;
}
void print_cstack( cstack s){
if(!is_cempty(s)){
printf("%d\n", s->data);
print_cstack(s->next);
}
}
boolean is_cfull(void){
cstack temp;
temp = (cstack) malloc (sizeof(struct cstacknode));
if(temp == NULL)
return TRUE;
else {
free(temp);
return FALSE;
}
}
boolean is_cempty( cstack s){
if (s == NULL)
return TRUE;
else
return FALSE;
}
3) This is cstack.h file
#ifndef __CSTACK_H_
#define __CSTACK_H_
#include "boolean.h"
typedef struct cstacknode{
char data;
struct cstacknode *next;
}*cstack;
void init_cstack(cstack *);
void cpush(cstack*,char);
char cpop(cstack *);
boolean is_cfull(void);
boolean is_cempty(cstack);
void print_cstack(cstack);
#endif
4) This is boolean.h file
#ifndef BOOLEAN_H
#define BOOLEAN_H
typedef int boolean;
#define TRUE 1
#define FALSE 0
#endif```
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 am currently trying to make a little user prompt were a function pointer gets assigned. My problem is that I can't get the now assigned function pointer out in main again.
The code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
double print_2 (void);
double print_1 (void);
void promt_user_input(double (*fn)(void));
//program to test funtion pointers inside funtions
//proof of consept
int main(void) {
double result;
double (*fn)(void);
promt_user_input(fn);
//result = *fn;
printf("het %lf",(fn)());
//This will not print no matter what i do.
}
void promt_user_input(double (*fn)(void)) {
int coice;
printf("Enter 1 or 2\n");
scanf(" %d",&coice);
switch(coice) {
case 1: *(&fn) = print_1; printf("you typed 1\n"); break;
case 2: *(&fn) = print_2; printf("you typed 2\n"); break;
default: printf("INVALID INPUT"); break;
}
printf("hi %lf\n",(fn)());
}
double print_1 (void){
printf("This is option 1\n");
return 1;
}
double print_2 (void){
printf("This is option 2\n");
return 2;
}
It compiles just fine, and the function is assigned correctly, because of the printf inside the prompt_user_input function prints the correct values. But outside of that function, it seems like it doesn't work. The printf function won't even run.
In the main() function you define uninitialized pointer to function fn and you pass it (by value) to another function promt_user_input which initializes it internally by either print_1 or print_2 based on the user input...
But when the flow goes back to the main(), the fn inside main() remained initialized. Dereferencing it causes undefined behavior. In order to initialize fn properly, you need to pass its address to promt_user_input and of course its signature has to be updated properly (input argument should be of type pointer to pointer to function or make it return the function pointer, whatever you prefer).
#include <stdio.h>
double print_2 (void);
double print_1 (void);
void promt_user_input(double (**fn)(void));
int main(void)
{
double result;
double (*fn)(void);
fn = NULL;
promt_user_input(&fn);
if (fn)
{
printf("het %lf",(fn)());
}
return 0;
}
void promt_user_input(double (**fn)(void))
{
unsigned int coice;
int res;
printf("Enter 1 or 2\n");
res = scanf("%u",&coice);
if (res != 1 || !coice || coice > 2)
{
printf("Invalid input!\n");
return;
}
switch(coice)
{
case 1: *fn = print_1; printf("you typed 1\n"); break;
case 2: *fn = print_2; printf("you typed 2\n"); break;
}
printf("hi %lf\n",(*fn)());
}
double print_1 (void)
{
printf("This is option 1\n");
return 1.0;
}
double print_2 (void)
{
printf("This is option 2\n");
return 2.0;
}
Few additional remarks:
You have to check for the return value of scanf to take care of invalid input.
Due to invalid input, the fn will remain uninitialized so you must not dereference it in such case. You need either initialize the fn to some invalid value and then check if it has a valid value before using it or make promt_user_input return a status which will indicate if the input argument was initialized successfully.
double constants must have floating point: 1-->int, 1.0 --> double
Prefer using unsigned types when negative values have no meaning (like coice).
int main(void) should return an int value at the end of the flow.
Since C is pass by value, you need to pass a pointer-to-pointer to the promt_user_input function:
int main(void)
{
double (*fn)(void);
promt_user_input(&fn);
printf("het %lf",fn());
}
void promt_user_input(double (**fn)(void))
{
int coice;
printf("Enter 1 or 2\n");
scanf(" %d", &coice);
switch(coice){
case 1: *fn = print_1; printf("you typed 1\n"); break;
case 2: *fn = print_2; printf("you typed 2\n"); break;
default: printf("INVALID INPUT"); break;
}
}
Things become easier to understand if you create a typedef:
typedef double (*func)(void);
void promt_user_input(func *fn);
int main(void)
{
func fn;
promt_user_input(&fn);
printf("het %lf", fn());
}
void promt_user_input(func *fn)
{
// Same as above....
Then you can avoid the pointer-to-pointer by having the function return a value:
typedef double (*func)(void);
func promt_user_input();
int main(void)
{
func fn = promt_user_input();
if (NULL != fn) {
printf("het %lf", fn());
}
}
func promt_user_input()
{
int coice;
printf("Enter 1 or 2\n");
scanf(" %d", &coice);
switch(coice){
case 1:
printf("you typed 1\n");
return print_1;
case 2:
printf("you typed 2\n");
return print_2;
default:
printf("INVALID INPUT");
return NULL;
}
}
In my code I have allocated some memory with my struct Song pointer called ptr
.
What I'm now trying to do is to create a second pointer that always point to the first struct in the allocated memory and use that to loop through all when I want to print the information.
It looks something like this in main:
#include "FuncDek.h"
#include <locale.h>
#include <crtdbg.h>
int main()
{
//For swedish and check memory leak
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
setlocale(LC_ALL, "swedish");
//Create with starting size of 5
Song *ptr = (Song *)malloc(sizeof(Song) * 5);
Song *start = &(ptr[0]);
int menuChoice = 0;
int nrOfSongs = 0;
do
{
system("cls");
menuChoice = menu();
switch (menuChoice)
{
case 1:
addSong(&ptr, &nrOfSongs);
break;
case 2:
showList(&start, nrOfSongs, &ptr);
break;
default:
printf("\nFelaktigt val, försök igen\n");
system("pause");
break;
}
} while (menuChoice != 0);
//TODO Free memory
//free(ptr);
system("pause");
return 0;
}
And I have to files that contains the function declarations/definitions which looks something like this:
#ifndef FUNCDEK
#define FUNCDEK
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char title[30];
char artist[30];
unsigned int year;
} Song;
int menu();
void addSong(Song *ptr, int *nrOfSongs);
void showList(Song *start, int nrOfSongs, Song *ptr);
#endif
And:
#include "FuncDek.h"
#pragma warning(disable: 4996)
//Show menu and save the users choice
int menu()
{
fflush(stdin);
int choice = 0;
printf("Menyval på låtlista\n");
printf("-------------------------\n");
printf("1. Lägg till låt \n");
printf("2. Visa låtlista \n");
printf("3. Blanda låtlistan \n");
printf("4. Spara till fil \n");
printf("0. Avsluta program \n");
scanf("%d", &choice);
getchar();
/*TODO FELHANTERING*/
return choice;
}
//Add song to list
void addSong(Song *ptr, int *nrOfSongs)
{
system("cls");
Song temp;
printf("Ange låtens namn:\n");
int sizeOfTitle = sizeof(temp.title) / sizeof(temp.title[0]);
fgets(temp.title, sizeOfTitle, stdin);
printf("Ange artistens namn:\n");
int sizeOfArt = sizeof(temp.artist) / sizeof(temp.artist[0]);
fgets(temp.artist, sizeOfArt, stdin);
printf("Ange året låtens släpptes: \n");
scanf("%d", &temp.year);
for (int i = 0; i < sizeOfTitle; i++)
{
ptr->artist[i] = temp.artist[i];
ptr->title[i] = temp.title[i];
}
ptr->year = temp.year;
*ptr++;
*nrOfSongs = *nrOfSongs + 1;
}
//Print all from list
void showList(Song *start, int nrOfSongs, Song *ptr)
{
system("cls");
printf("Song list\n");
printf("-----------------------------\n");
for (int i = 0; i < 1; i++)
{
printf("Låt: %s \n", start->title);
printf("Artist: %s \n", start->artist);
printf("År: %d \n", start->year);
start++;
}
system("pause");
}
But when I run the showList function I get garbage values and I can also see that I don't read on the correct memory-location.
So my questions is how do I make my pointer called start to point to the first memory block in ptr?
You can consider using a C linked list.
Here is a good example.
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.