Problem with playing the next song automatically with SDL_Mixer - c

I have this c program which used to search for the mp3 files of given directory and add the files data to linked list.i use SDL2 for audio handling. so much far i would be able to get the playing of mp3 file and what i'm facing here is that i don't know how to play the next song when the first song is played in the linked list.
Here is my code for the program.
#include <dirent.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "file_handle.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
struct tags
{
const char *artist;
} tags;
Mix_Music *music = NULL;
bool loadmedia(char *filepath);
void play();
void init();
void load_file_directory(char *dir_path);
int main(int argc, char *argv[])
{
char *file_path;
if (argc <= 1)
{
fprintf(stderr, "no arguments provided!\n");
}
else
{
file_path = argv[2];
}
if (file_path)
{
load_file_directory(file_path);
}
init();
int count = 0;
for (struct song *node = head; node; node = node->next)
{
printf("%s\n", node->file_path);
}
for (struct song *node = head; node; node = node->next)
{
printf("%s\n", node->file_path);
printf("count is %d\n", count);
count++;
Mix_Music *song = Mix_LoadMUS(node->file_path);
if (Mix_PlayMusic(song, 1) != 0)
{
printf("something\n");
}
while (!SDL_QuitRequested())
SDL_Delay(250);
Mix_FreeMusic(song);
}
// char *file = argv[1];
// bool status = loadmedia(file);
// if(status){
// printf("%s - %s\n",Mix_GetMusicArtistTag(music),Mix_GetMusicTitleTag(music));
// if(Mix_PlayMusic(music,1)){
// printf("something wrong");
// Mix_FreeMusic(music);
// }
// }
// while(!SDL_QuitRequested())
// SDL_Delay(250);
}
bool loadmedia(char *file_path)
{
bool success = false;
if (file_path)
{
music = Mix_LoadMUS(file_path);
success = true;
}
else
{
printf("File Loaded Failed\n");
}
return success;
}
void init()
{
bool success;
if (SDL_Init(SDL_INIT_AUDIO) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
success = false;
}
if (Mix_Init(MIX_INIT_MP3) != MIX_INIT_MP3)
{
fprintf(stderr, "could not initialized mixer\n", Mix_GetError());
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
{
printf("SDL_mixer could not be initialized %s\n", Mix_GetError());
success = false;
}
}

Related

Why am I getting an "undefined reference to `parseAndExecute' " error here?

I'm using an online tutorial on how to make a Text Adventure game (in VSC) and came across a really annoying issue. Even after copying all the source code from the tutorial, I receive an 'undefined reference' error. I tried editing the 'tasks.json' file as described here: undefined reference error in VScode
but with no success.
The game consists of multiple c files in order to work, the source code is at the bottom of the page here: https://helderman.github.io/htpataic/htpataic05.html
Here's all the files, Thanks a lot in advance for any help!
<main.c>
#include <stdbool.h>
#include <stdio.h>
#include "parsexec.h"
static char input[100] = "look around";
static bool getInput(void)
{
printf("\n--> ");
return fgets(input, sizeof input, stdin) != NULL;
}
int main()
{
printf("Welcome to Little Cave Adventure.\n");
while (parseAndExecute(input) && getInput());
printf("\nBye!\n");
return 0;
}
<parsexec.h>
extern bool parseAndExecute(char *input);
<parsexec.c>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "location.h"
#include "inventory.h"
bool parseAndExecute(char *input)
{
char *verb = strtok(input, " \n");
char *noun = strtok(NULL, " \n");
if (verb != NULL)
{
if (strcmp(verb, "quit") == 0)
{
return false;
}
else if (strcmp(verb, "look") == 0)
{
executeLook(noun);
}
else if (strcmp(verb, "go") == 0)
{
executeGo(noun);
}
else if (strcmp(verb, "get") == 0)
{
executeGet(noun);
}
else if (strcmp(verb, "drop") == 0)
{
executeDrop(noun);
}
else if (strcmp(verb, "give") == 0)
{
executeGive(noun);
}
else if (strcmp(verb, "ask") == 0)
{
executeAsk(noun);
}
else if (strcmp(verb, "inventory") == 0)
{
executeInventory();
}
else
{
printf("I don't know how to '%s'.\n", verb);
}
}
return true;
}
<location.c>
#include <stdio.h>
#include <string.h>
#include "object.h"
#include "misc.h"
#include "noun.h"
void executeLook(const char *noun)
{
if (noun != NULL && strcmp(noun, "around") == 0)
{
printf("You are in %s.\n", player->location->description);
listObjectsAtLocation(player->location);
}
else
{
printf("I don't understand what you want to see.\n");
}
}
void executeGo(const char *noun)
{
OBJECT *obj = getVisible("where you want to go", noun);
if (obj == NULL)
{
// already handled by getVisible
}
else if (obj->location == NULL && obj != player->location)
{
printf("OK.\n");
player->location = obj;
executeLook("around");
}
else
{
printf("You can't get much closer than this.\n");
}
}
<location.h>
extern void executeLook(const char *noun);
extern void executeGo(const char *noun);
<object.c>
#include <stdio.h>
#include "object.h"
OBJECT objs[] = {
{"an open field", "field" , NULL },
{"a little cave", "cave" , NULL },
{"a silver coin", "silver" , field },
{"a gold coin" , "gold" , cave },
{"a burly guard", "guard" , field },
{"yourself" , "yourself", field }
};
<object.h>
typedef struct object {
const char *description;
const char *tag;
struct object *location;
} OBJECT;
extern OBJECT objs[];
#define field (objs + 0)
#define cave (objs + 1)
#define silver (objs + 2)
#define gold (objs + 3)
#define guard (objs + 4)
#define player (objs + 5)
#define endOfObjs (objs + 6)
<noun.c>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "object.h"
static bool objectHasTag(OBJECT *obj, const char *noun)
{
return noun != NULL && *noun != '\0' && strcmp(noun, obj->tag) == 0;
}
static OBJECT *getObject(const char *noun)
{
OBJECT *obj, *res = NULL;
for (obj = objs; obj < endOfObjs; obj++)
{
if (objectHasTag(obj, noun))
{
res = obj;
}
}
return res;
}
OBJECT *getVisible(const char *intention, const char *noun)
{
OBJECT *obj = getObject(noun);
if (obj == NULL)
{
printf("I don't understand %s.\n", intention);
}
else if (!(obj == player ||
obj == player->location ||
obj->location == player ||
obj->location == player->location ||
obj->location == NULL ||
obj->location->location == player ||
obj->location->location == player->location))
{
printf("You don't see any %s here.\n", noun);
obj = NULL;
}
return obj;
}
OBJECT *getPossession(OBJECT *from, const char *verb, const char *noun)
{
OBJECT *obj = NULL;
if (from == NULL)
{
printf("I don't understand who you want to %s.\n", verb);
}
else if ((obj = getObject(noun)) == NULL)
{
printf("I don't understand what you want to %s.\n", verb);
}
else if (obj == from)
{
printf("You should not be doing that to %s.\n", obj->description);
obj = NULL;
}
else if (obj->location != from)
{
if (from == player)
{
printf("You are not holding any %s.\n", noun);
}
else
{
printf("There appears to be no %s you can get from %s.\n",
noun, from->description);
}
obj = NULL;
}
return obj;
}
<noun.h>
extern OBJECT *getVisible(const char *intention, const char *noun);
extern OBJECT *getPossession(OBJECT *from, const char *verb, const char *noun);
<inventory.c>
#include <stdio.h>
#include "object.h"
#include "misc.h"
#include "noun.h"
#include "move.h"
void executeGet(const char *noun)
{
OBJECT *obj = getVisible("what you want to get", noun);
if (obj == NULL)
{
// already handled by getVisible
}
else if (obj == player)
{
printf("You should not be doing that to yourself.\n");
}
else if (obj->location == player)
{
printf("You already have %s.\n", obj->description);
}
else if (obj->location == guard)
{
printf("You should ask %s nicely.\n", obj->location->description);
}
else
{
moveObject(obj, player);
}
}
void executeDrop(const char *noun)
{
moveObject(getPossession(player, "drop", noun), player->location);
}
void executeAsk(const char *noun)
{
moveObject(getPossession(actorHere(), "ask", noun), player);
}
void executeGive(const char *noun)
{
moveObject(getPossession(player, "give", noun), actorHere());
}
void executeInventory(void)
{
if (listObjectsAtLocation(player) == 0)
{
printf("You are empty-handed.\n");
}
}
<inventory.h>
extern void executeGet(const char *noun);
extern void executeDrop(const char *noun);
extern void executeAsk(const char *noun);
extern void executeGive(const char *noun);
extern void executeInventory(void);
<misc.c>
#include <stdio.h>
#include "object.h"
OBJECT *actorHere(void)
{
OBJECT *obj;
for (obj = objs; obj < endOfObjs; obj++)
{
if (obj->location == player->location && obj == guard)
{
return obj;
}
}
return NULL;
}
int listObjectsAtLocation(OBJECT *location)
{
int count = 0;
OBJECT *obj;
for (obj = objs; obj < endOfObjs; obj++)
{
if (obj != player && obj->location == location)
{
if (count++ == 0)
{
printf("You see:\n");
}
printf("%s\n", obj->description);
}
}
return count;
}
<misc.h>
extern OBJECT *actorHere(void);
extern int listObjectsAtLocation(OBJECT *location);
<move.c>
#include <stdio.h>
#include "object.h"
static void describeMove(OBJECT *obj, OBJECT *to)
{
if (to == player->location)
{
printf("You drop %s.\n", obj->description);
}
else if (to != player)
{
printf(to == guard ? "You give %s to %s.\n" : "You put %s in %s.\n",
obj->description, to->description);
}
else if (obj->location == player->location)
{
printf("You pick up %s.\n", obj->description);
}
else
{
printf("You get %s from %s.\n",
obj->description, obj->location->description);
}
}
void moveObject(OBJECT *obj, OBJECT *to)
{
if (obj == NULL)
{
// already handled by getVisible or getPossession
}
else if (to == NULL)
{
printf("There is nobody here to give that to.\n");
}
else if (obj->location == NULL)
{
printf("That is way too heavy.\n");
}
else
{
describeMove(obj, to);
obj->location = to;
}
}
<move.h>
extern void moveObject(OBJECT *obj, OBJECT *to);
Image of the issue in VSC:
https://i.stack.imgur.com/5mkzV.png
Your code doesn't compile as it relies on header files you haven't shared with us, and executeAsk() for which we have no implementation. I removed the missing bits from parsexec.c:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool parseAndExecute(char *input) {
char *verb = strtok(input, " \n");
char *noun = strtok(NULL, " \n");
if (verb != NULL) {
printf("I don't know how to '%s'.\n", verb);
}
return true;
}
and was then able to build and execute your game:
gcc main.c parsexec.c -o game && ./game
Welcome to Little Cave Adventure.
I don't know how to 'look'.
--> look
I don't know how to 'look'.
--> ^C
This tells me it's a build issue. Specifically, you are probably not linking parsexec.o to your binary.
It turned out to be a faulty compiler/settings in VSC as the code ran fine on a different machine.

Why is index not changing after returning to parent after executing child process

I am trying to implement a simple shell with history which takes process batch files as input and execute them.
My header file head.h looks like:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
typedef struct Process{
int index;
char **args;
} Proc_t;
typedef struct historyNode{
Proc_t Process;
struct historyNode *next;
struct historyNode * prev;
} his_t;
//Function Prototypes
his_t * createNode(his_t *head, Proc_t *Process);
char** ParseString(char *buffer);
void execProcess(his_t *head, Proc_t *Process);
void HistoryBrief(his_t *head);
void HistoryFull(his_t *head);
void printProcess(Proc_t Process);
void printProcessCmd(Proc_t Process);
int isNumber(char *arg);
Proc_t *get_Process(his_t *head, int index);
Proc_t *existsInHistory(his_t *head, char **args);
Here is the main.c :
#include "head.h"
his_t * head = NULL;
int main(int argc, char ** argv)
{
int index = 1;
for(int i = 1 ; i<argc;i++)
{
char buffer[1000]; // to store the command read from file
FILE *f = fopen(argv[i],"r");
while(fgets(buffer,sizeof(buffer), f) != NULL)
{
char** currProcessArgs = ParseString(buffer);
Proc_t *currProcess = (Proc_t *)malloc(sizeof(Proc_t));
currProcess->index = index;
//printf("index of currProcess: %d\n",currProcess->index);
currProcess->args = currProcessArgs;
//printProcess(*currProcess);
if(head == NULL)
{
head = createNode(head, currProcess);
//printf("Process name:%s, head address:%p\n", head, head->Process.args[0]);
}
else
{
createNode(head, currProcess);
//printf("Process name:%s, head address:%p\n", head, head->Process.args[0]);
}
printf("\n%d index in loop\n", index);
index++;
execProcess(head,currProcess);
//index++;
}
// HistoryBrief(head);
//HistoryFull(head);
fclose(f);
}
//Ignore the while part for now
while(1)
{
char inputBuffer[1000];
puts("Please enter a command!: ");
scanf("%[^\n]%*c", inputBuffer);
//fflush(stdin);
printf("inputBuffer: %s\n",inputBuffer);
char **userCmdArgs = ParseString(inputBuffer);
if(strcmp(userCmdArgs[0],"EXEC")==0)
{
if(isNumber(userCmdArgs[1])==0)
{
Proc_t *userCmd = (Proc_t *)malloc(sizeof(Proc_t));
userCmd->index=index;
userCmd->args = userCmdArgs+1;
userCmd = existsInHistory(head, userCmd->args);
if(userCmd!=NULL)
{
puts("This Command Already exists in History!!");
// execProcess(userCmd);
}
else
{
puts("This Command doesn't exist in history. Adding it to the history");
createNode(head,userCmd);
//execProcess(userCmd);
}
}
else
{
Proc_t *userProcessWithIndex = get_Process(head, atoi(userCmdArgs[1]));
if(userProcessWithIndex==NULL)
{
puts("Command with the given index doesn't exist!!\n");
}
else
execProcess(head, userProcessWithIndex);
}
}
else if(strcmp(userCmdArgs[0], "HISTORY")==0)
{
if(strcmp(userCmdArgs[1],"BRIEF")==0)
{
printProcess(head->Process);
HistoryBrief(head);
}
else
{
HistoryFull(head);
}
}
else if(strcmp(userCmdArgs[0],"STOP")==0)
{
puts("Exiting Normally, Bye!!\n");
break;
}
}
return 0;
}
here is history.c
#include "head.h"
his_t *createNode(his_t *head, Proc_t *Process)
{
his_t * new_node = (his_t *) malloc(sizeof(his_t));
new_node->Process = *Process;
new_node->next = NULL;
new_node->prev = NULL;
if(head == NULL)
{
head = new_node;
return head;
}
else
{
his_t * temp = head;
while(temp->next != NULL)
{
temp=temp->next;
}
temp->next=new_node;
new_node->prev=temp;
return new_node;
}
}
Proc_t *existsInHistory(his_t *head, char **args)
{
his_t *temp = head;
int i = 0;
int exists = 1;
while(temp!=NULL)
{
while(args[i]!=NULL && temp->Process.args[i]!=NULL)
{
if(args[i]==temp->Process.args[i])
exists=1;
else
{
exists = 0;
break;
}
}
if(exists)
{
Proc_t *tempProc = (Proc_t *)malloc(sizeof(Proc_t));
tempProc = &(temp->Process);
return tempProc;
}
temp = temp->next;
return NULL;
}
}
Proc_t *get_Process(his_t *head, int index)
{
his_t * temp = head;
while(temp!=NULL)
{
if(temp->Process.index == index)
break;
temp=temp->next;
}
if(temp!=NULL)
{
Proc_t *procTemp = (Proc_t *)malloc(sizeof(Proc_t));
procTemp = &(temp->Process);
return procTemp;
}
else
return NULL;
}
void HistoryBrief(his_t *head)
{
his_t * temp = head;
while(temp->next!=NULL)
{
printf("Address of head: %p\n", temp);
if(temp->prev!=NULL)
printProcessCmd(temp->prev->Process);
printProcessCmd(temp->Process);
temp=temp->next;
}
}
void HistoryFull(his_t *head)
{
his_t *temp = head;
while(temp->next!=NULL)
{
printProcess(temp->Process);
temp = temp -> next;
}
}
}
Here is process.c
#include "head.h"
int isNumber(char *arg)
{
int i = 0;
while(arg[i]!='\0')
{
if(isdigit(arg[i])==0)
return 0;
i++;
}
return 1;
}
char** ParseString(char *buffer)
{
int buff_size = strlen(buffer);
if(buffer[buff_size-1]=='\n')
buffer[buff_size-1]='\0';
char **args =(char *)malloc(30*sizeof(char *));// array for storing arguments
int i = 0;
char *arg = strtok(buffer," ");
while(arg !='\0')
{
args[i] = arg;
arg = strtok(NULL," ");
i++;
}
args[i] = '\0';
puts("\n");
int k =0;
while(args[k]!=NULL)
{
printf("%s ",args[k]);
k++;
}
return args;
}
void printProcess(Proc_t Process)
{
printf("%d.",Process.index);
puts("args: ");
int i = 0;
while(Process.args[i]!=NULL)
{
printf("%s ",Process.args[i]);
i++;
}
puts("\n");
}
void printProcessCmd(Proc_t Process)
{
printf("%d.%s\n",Process.index,Process.args[0]);
}
void execProcess(his_t *head,Proc_t *Process)
{
int pid = fork();
if(pid==0)
{
printf("Currently Executing: index:%d||command:%s\n\n",Process->index, Process->args[0]);
execvp(Process->args[0],Process->args);
}
else if(pid)
{
wait(NULL);
(head->Process.index)++;
printf("index of head afgter returning to parent process: %d\n",head->Process.index);
printf("%s, cmd of head process after returning to parent\n",head->Process.args[0]);
}
else
return 0;
}
So basically my program will take input as text files containing linux commands. Each command is written on a different line.
Example file -
ls -al
echo Hello World
touch newfile.c
ps
I have created a doubly linked list for storing history of commands.
When I call HistoryBrief() It prints 4 ps instead of printing each command. Also, after calling fork, the index is changing inside the parent but not the child. Why is that??

How to solve exception thrown in traversing forest

Question: Compute numbers of leaves in forest. Promblem: After debugging and printing a part of data, when I traverse printf("%d ", node->data);, incurred in a runtime error, that is, exception thrown: read access violation.
MainFunc.c
#include "AllFun.h"
int main(int argc, char* argv[])
{
CsNode* tree = (CsNode*)malloc(sizeof(CsNode));
if (tree) {
tree->firstchild = NULL;
tree->nextsibling = NULL;
CreateTree(&tree);
preOrder(tree);
int leaves = CountForestLeaves(tree);
printf("leaves: %d", leaves);
}
return 0;
}
AllFun.h
#include <stdio.h>
#include <stdlib.h>
typedef struct CsNode {
struct CsNode* firstchild;
struct CsNode* nextsibling;
int data;
}CsNode;
void CreateTree(CsNode** node);
void preOrder(CsNode* node);
int CountForestLeaves(CsNode* tree);
OtheFunc.c
#include "AllFun.h"
void CreateTree(CsNode** node)
{
int data;
printf("please input data: ");
scanf_s("%d", &data);
if (data != -1) {
*node = (CsNode*)malloc(sizeof(CsNode));
(*node)->data = data;
(*node)->firstchild = NULL;
(*node)->nextsibling = NULL;
CreateTree(&(*node)->firstchild);
CreateTree(&(*node)->nextsibling);
}
}
void preOrder(CsNode* node)
{
if (node != NULL) {
printf("%d ", node->data);
preOrder(node->firstchild);
preOrder(node->nextsibling);
}
}
int CountForestLeaves(CsNode* tree)
{
if (tree == NULL)
return 0;
if (tree->firstchild == NULL)
return 1 + CountForestLeaves(tree->nextsibling);
else {
return CountForestLeaves(tree->firstchild) + CountForestLeaves(tree->nextsibling);
}
}

CS50 "Speller": Problem with dictionary file

I'm working on CS59 Week 5's "Speller" assignment. Currently, I'm trying to write the unload function with a test dictionary file on my desktop. But for some reason, line 91 (while(!feof(dictionary))) is returning an error:
"request for member '_flag' in something not a structure or a union"
I'm working from a new computer. My previous computer did not return this error. Can someone please explain what's going on here and how I can fix it? Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
unsigned int HASH_MAX = 50;
unsigned int LENGTH = 20;
unsigned int hash (const char *word);
bool load(char *dictionary);
bool check (char *word);
bool unload (void);
void print (void);
typedef struct _node
{
char *word[20];
struct _node *next;
} node;
node *HASH_TABLE[50];
int main(int argc, char *argv[])
{
FILE *dictionary = fopen("C:/Users/aaron/Desktop/Dictionary.txt", "r");
if(!dictionary)
{
printf("FILE NOT FOUND\n");
return 1;
}
if (load(dictionary))
{
// print "LIST (number): {(name, address), ...}\n
print();
}
int lois = hash("Lois");
printf("\n%s\n", HASH_TABLE[lois]->word);
if (check("StEwIe"))
{
printf("STEWIE found\n");
}
else if (!check("StEwIe"))
{
printf("STEWIE not found\n");
}
if (check("Tron"))
{
printf("TRON found\n");
}
else if (!check("Tron"))
{
printf("TRON not found\n");
}
if (unload())
{
print();
}
}
unsigned int hash(const char *word) // hash code function (FIND A BETTER ALGORITHM)
{
char word_conv[LENGTH + 1]; // store converted word for uniform key
unsigned int code = 0; // hash code
for (int i = 0; i < strlen(word); i++) // set all letters in the word to lower case
{
word_conv[i] = tolower(word[i]);
}
for (int j = 0; j < strlen(word_conv); j++) // for all letters in converted word, add ascii value to code and multiply by 3
{
code += word_conv[j];
code *= 3;
}
code = code % HASH_MAX; // set code to remainder of current code divided by maximum hash table size
return code;
}
bool load (char *dictionary)
{
char word[LENGTH+1];
while(!feof(dictionary))
{
fscanf(dictionary, "%s", word);
node *new_n = malloc(sizeof(node));
strcpy(new_n->word, word);
new_n->next = NULL;
unsigned int code = hash(word);
if (HASH_TABLE[code] == NULL)
{
HASH_TABLE[code] = new_n;
}
else if (HASH_TABLE[code] != NULL)
{
node *trav = HASH_TABLE[code];
while (trav->next != NULL)
{
trav = trav->next;
}
if (trav->next == NULL)
{
trav->next = new_n;
}
}
}
return true;
}
bool check (char *word)
{
unsigned int code = hash(word);
node *check = malloc(sizeof(node));
check = HASH_TABLE[code];
while (check != NULL)
{
if (strcasecmp(check->word, word) == 0)
return true;
}
if (check == NULL)
return false;
}
bool unload (void)
{
for (int i = 0; i < HASH_MAX; i++)
{
while (strcmp(HASH_TABLE[i]->word, "FREE" != 0)
{
node *curr = HASH_TABLE[i];
node *prev = NULL;
while (curr != NULL)
{
prev = curr;
curr = curr->next;
}
strcpy(prev->word, "FREE");
}
}
return true; // freed successfully
}
void print (void)
{
for (int i = 0; i < HASH_MAX; i++)
{
node *check = HASH_TABLE[i];
printf("LIST %02d: {", i);
while (check != NULL)
{
printf("%s, ", check->word);
check = check->next;
}
printf("}\n");
}
}

void * function pointer

I have made a typedef for a function pointer that takes in an integer and returns a void *:
typedef void* (*fp)(int index);
I then made a struct that contains a fp and another struct of the same type:
typedef struct fp_holder {
fp function_pointer;
iterable *next;
} fp_holder;
I am trying to figure out how to call fp inside a fp_holder.
To test this out, I did the following:
void *test_fp(int index) {
if (index == 0) {
printf('H');
fflush(stdout);
return [something_that_works];
}
else if (index == 1) {
printf('e');
fflush(stdout);
return [something_that_works];
}
else if (index == 2) {
printf('l');
fflush(stdout);
return [something_that_works];
}
else if (index == 3) {
printf('l');
fflush(stdout);
return [something_that_works];
}
else if (index == 4) {
printf('o');
fflush(stdout);
return [something_that_works];
}
else {
return (void *) NULL;
}
}
fp_holder *a = (fp_holder *) malloc(sizeof(fp_holder));
a->function_pointer = test_fp;
a->next = NULL;
So with all that setup, I tried to call a's function_pointer by trying the following:
a->function_pointer(0);
(*a->function_pointer)(0);
((*)a->function_pointer)(0);
I just cannot figure out why those are not working.
Help would be appreciated! :)
EDIT
What I am trying to do:
Call a's function_pointer with an argument.
I will try out some answers right now and see what happens.
EDIT2
Answered! I was calling it right by doing a->function_pointer(0) but what was giving me a segmentation error [which is what my issue was - and maybe I should have clarified this] was the printf statement and NOT my call. printf needs a string not the char as I put in.
Does your original code actually do
printf('H');
instead of
printf("H");
?
Simplified version of the code you posted, with correct arguments to printf:
#include <stdio.h>
typedef void* (*function_pointer_t)(int index);
struct function_holder {
function_pointer_t callback;
};
void* testFn(int i)
{
printf("testFn %d\n", i);
}
int main(void) {
struct function_holder fh = { testFn };
struct function_holder* fhp = &fh;
fh.callback = testFn;
fh.callback(1);
fhp->callback(2);
return 0;
}
works as expected: http://ideone.com/1syLlG
your code has couple of errors. I am not sure what you are trying to achieve by this code, however here is your working code.
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
typedef void* (*fp)(int index);
typedef struct fp_holder {
fp function_pointer;
struct fp_holder *next;
} fp_holder;
void *test_fp(int index) {
if (index == 0) {
printf("H");
fflush(stdout);
return "H";
}
else if (index == 1) {
printf("e");
fflush(stdout);
return "e";
}
else if (index == 2) {
printf("l");
fflush(stdout);
return "l";
}
else if (index == 3) {
printf("l");
fflush(stdout);
return "l";
}
else if (index == 4) {
printf("o");
fflush(stdout);
return "o";
}
else {
return (void *) NULL; }
}
int main() {
fp_holder *a = (fp_holder *) malloc(sizeof(fp_holder));
a->function_pointer = test_fp;
a->next = NULL;
a->function_pointer(0);
}

Resources