C error C2660: 'Menu' : function does not take 3 arguments - c

I am new to programming and do not understand this error.
I have the same arguments in the Menu () function and when I call the same function in the menu_principal () function.
In function menu_principal(), I want execute the switch-case statement by the function Menu() with 'option' variable.
Can you help please?
int main()
{
void menu_principal();
return 0;
}
void menu_principal()
{
bool stop = true;
int option;
const char *title = "MENU PRINCIPAL";
const char *options_menu[] = { "ARTIGOS", "CLIENTES", "ORCAMENTOS", "SAIR" };
int n_options = 4;
do
{
option = Menu(title, options_menu, n_options);
switch (option)
{
case 1:
Menu_Item();
break;
case 2:
Menu_Client();
break;
case 3:
Menu_Billing();
break;
case 4:
stop = false;
break;
}
} while (stop);
}
int Menu(const char *title1, const char *options_menu1[], int n_options1)
{
int OptionSelected= 1;
int key;
bool stop = true;
do
{
system("cls");
gotoxy(5, 3 + OptionSelected); printf(">>");
gotoxy(15, 2); printf("%s", title1);
for (int i = 0; i < n_options1; i++)
{
gotoxy(10, 4 + i);
printf("%s ", options_menu1[i]);
}
do
{
key = _getch();
} while (key != KEY_UP && key != KEY_DOWN && key != KEY_ENTER );
switch (key)
{
case KEY_UP:
OptionSelected--;
if (OptionSelected < 1)
{
OptionSelected = n_options1;
}
break;
case KEY_DOWN:
OptionSelected--;
if (OptionSelected > n_options1)
{
OptionSelected = 1;
}
break;
case KEY_ENTER:
stop = false;
break;
}
} while (stop);
return OptionSelected;
}

The compiler reads your program top to bottom, so it sees:
option = Menu(title, options_menu, n_options);
On this line, you call a previously unknown function, Menu.
Because the function is unknown, the compiler assumes it will be int Menu(void). (takes no parameters, returns an int).
That assumption is obviously different from how Menu eventually gets declared.
To fix this, declare the function properly near the top of your file:
int Menu(const char *title1, const char *options_menu1[], int n_options1);
Then, when the compiler encounters your function-call, it will not assume a declaration, it will use the declaration you already provided (takes 3 parameters, and returns an int)

Related

how can i assign a randomly generated integer to a string in C?

i'm trying to make a slot machine type thing and i wanted to assign the randomly generated numbers to certain symbols like 1 = cherry, 2 = bell and so on so i could print out the results in symbol form at the end.
i tried putting the symbols as strings in an array and assigning the numbers to the elements in the array in each slot functions but it didn't work out... is there a way to do this?
here's the code i've written so far, minus the array attempts. any suggestions would be helpful! :D
EDIT: here's an example of what i've tried doing on one of the slots but it keeps saying i need a cast to assign the integer from a pointer (i've tried searching online but idk how to do this)
char * slotOne(int randOne, const char *symbols[])
{
randOne = rand() % 4 + 1;
if (randOne = 1)
{
randOne = *symbols;
}
if (randOne = 2)
{
randOne = *(symbols+1);
}
if (randOne = 3)
{
randOne = *(symbols+2);
}
else
{
randOne = *(symbols+3);
}
return randOne;
}
this is the part of my main function where i've tried declaring the string array:
int main()
{
int x, one, two, three;
const char *symbols[4] = {"bell", "orange", "cherry", "horseshoe"};
srand(time(NULL));
one = slotOne(x);
two = slotTwo(x);
three = slotThree(x);
printf("%s - %s - %s\n", one, two, three);
//...
}
not sure if %s or %c is the right type too...
At least these problems:
Code is assigning = when it should compare ==.
// if (randOne = 1)
if (randOne == 1)
The last if () { ... } else { ... } will cause one of the 2 blocks to execute. OP wants an if () { ... } else if () { ... } else { ... } tree.
// Problem code
if (randOne = 3) {
randOne = *(symbols+2);
} else {
randOne = *(symbols+3);
}
Suggest
if (randOne == 1) {
randOne = *symbols;
} else if (randOne == 2) {
randOne = *(symbols+1);
} else if (randOne == 3) {
randOne = *(symbols+2);
} else {
randOne = *(symbols+3);
}
Also research switch.
switch (randOne) {
case 1:
randOne = *symbols;
break;
case 2:
randOne = *(symbols+1);
break;
case 3:
randOne = *(symbols+2);
break;
default:
randOne = *(symbols+3);
break;
}
Or consider a coded solution:
randOne = *(symbols+(randOne-1));
But code needs to return a pointer to a string not an int and has no need to pass in randOne as a parameter.
const char * slotOne(const char *symbols[]) {
int randOne = rand() % 4;
return symbols[randOne];
}
Calling code also needs to adjust to receive a const char *, not an int.
// int one;
// one = slotOne(x);
const char *one = slotOne(symbols);

Double buffering and printf

I am having trouble with getting my other basic functions to work with double buffer.
for example in the code below, it runs and I can press either down or up to move my cursor, and when I press enter I am supposed to get a printf saying either making a new char, load, or goodbye.
It shows up for a split second but then it immediately disappears. In these situations rewind(stdin) and getchar(); solves this issue but for this code, nothing seems to work.
Please help.
#define _CRT_SECURE_NO_WARNINGS
#include "conioex.h"
#include "DblBuffer.h"
enum //
{
NEW_GAME = 20,
LOAD,
EXIT,
MAX_NUM
};
void main (void)
{
DblBuffer db;
int Cursor_X, Cursor_Y; // cursorlocation
bool Key_flag = false; // pressandtrue
int type = NEW_GAME; // type
Cursor_X = 20;
Cursor_Y = 1;
int flag = 1;
while (flag)
{
for (int i = 1; i <= 3; i++)
{
db.setCursorPos(20,i);
db.write(" ");
}
db.setCursorPos(25,1);
db.write("New Game\n");
db.setCursorPos(25,2);
db.write("Load\n");
db.setCursorPos(25,3);
db.write("Exit\n");
if (inport(PK_DOWN))
{
if (Key_flag == false)
{
Cursor_Y = Cursor_Y + 1;
type = type + 1;
Key_flag = true;
}
}
else if (inport(PK_UP))
{
if (Key_flag == false)
{
Cursor_Y = Cursor_Y - 1;
type = type - 1;
Key_flag = true;
}
}
else if (inport(PK_ENTER))
{
flag = 0;
break;
}
else
{
Key_flag = false;
}
if (Cursor_Y < 1)
{
Cursor_Y = 1;
}
if (Cursor_Y > 3)
{
Cursor_Y = 3;
}
if (type < NEW_GAME)
{
type = NEW_GAME;
}
if (type >= MAX_NUM)
{
type = MAX_NUM - 1;
}
db.setCursorPos(Cursor_X, Cursor_Y);
db.write("→");
db.swap();
}
if(type == NEW_GAME)
{
printf("making a new game");
}
if (type == LOAD)
{
printf("will load");
}
if (type == EXIT)
{
printf("goodbye");
}
rewind(stdin);
getchar();
}
As for your problem, by "then it immediately disappears" I assume that the console window disappears quickly?
That's because the program exits.
You need to flush the input buffer connected to stdin to remove all key presses you made (by reading from stdin) and then call getchar one extra time to get a a kind of confirmation that the user wants to exit.

Why my double pointer is null? [duplicate]

This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 5 years ago.
this is my code:
void n(FILE *f, int *pocet, char **spz) {
int i = 0;
int pocett = 0;
char* r = (char*)malloc(50 * sizeof(char));
if (spz != NULL) {
free(spz);
}
spz = (char**)malloc(sizeof(char*));
if (f == NULL) {
printf_s("File is null");
return;
}
while (fgets(r, 50, f)) {
switch (i % 6) {
case 1: {
if (i == 1) {
spz[0] = (char*)malloc(50 * sizeof(char));
spz[0] = r;
}
else {
spz = (char**) realloc(spz,((i - 1) / 6 + 1) * sizeof(char*));
spz[((i - 1) / 6)] = (char*)malloc(50 * sizeof(char));
strcpy_s(spz[(i-1)/6], 50 ,r);
}
break;
}
case 5: {
pocett++;
break;
}
}
i++;
}
*pocet = ++pocett;
}
and I call my function as this:
int main() {
FILE *f = NULL;
int c;
int pocet = 0;
int* p = &pocet;
char** spz = NULL;
while ((c = getchar()) != 'k') {
getchar();
switch (c) {
case 'v': {
v(&f);
break;
}
case 'o': {
//printf_s("AHOJ\n");
break;
}
case 'n': {
n(f, p, spz);
break;
}
case 's': {
s(spz, *p);
break;
}
case 'p': {
printf_s("AHOJ\n");
break;
}
case 'z': {
printf_s("AHOJ\n");
break;
}
default: {
printf_s("Skus znova\n");
break;
}
}
}
return 0;
}
EDIT: I have edited my code to add main method.
the problem is, when I pass the spz to another method after, it is null, that means I have to use it in method n() as triple pointer, but it is not working when I add asterisk before each spz in method n. Do you have any ideas how to fix this ?
When you call a function you pass a copy of the spz variable from the main() function to an spz variable in the n() function. Then, assignment in n() affects only its local spz.
If you want to get a pointer value back, you need to pass a pointer to the variable and the routine must dereference the pointer to reach the original variable:
void n( char ***spz_ptr) // a pointer to (char **) variable
{
*spz_ptr // dereferenced pointer. i.e. the main's spz
= malloc( ... );
}
void main()
{
char **spz;
n( & spz ); // pass a pointer to spz
if( spz == NULL) { // test the value assigned by n()
.... // handle the error
}
else {
.... // proceed with actual work
}
}

Escape delay with a button in a game

I have a problem with a piece of code for a game. I would like to know, how to break the time delay if I press the button.
List of files
At the end, the game writes your end score on the LCD for 10 seconds. And goes back to the wait for start. I want to keep that as it is - the only thing that I want to include is that if I press the button within those 10 seconds I want it to go immediately back to the wait for start.
Function code is here
void DrawGameScore()
{ //&RFONT_8X12 &RFONT_16X26
//char key;
//key = KBD_GetKey();
char txt[10];
UG_FontSelect(&RFONT_16X26);
UG_SetForecolor(C_WHITE);
switch (level){
case 1:
UG_PutString(60,130,"Peasant Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 2:
UG_PutString(60,130,"Knight Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 3:
UG_PutString(60,130,"Queen Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 4:
UG_PutString(60,130,"King Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
case 5:
UG_PutString(60,130,"God Score:");
sprintf(txt,"%d",score);
UG_PutString(120,160,txt);
_delay_ms(10000);
break;
}
//UG_PutString(60,130,"Final Score:");
//sprintf(txt,"%d",score);
//UG_PutString(120,160,txt);
//_delay_ms(1000);
}
When the game is over this function draws your score based on your level. In this next function i am calling drawgamescore function, which is in dsip_end_score makro.
int EndOfGame()
{
char key;
//static int state;
int result = 1;
key = KBD_GetKey();
display_msg = DSIP_END_SCORE;
if (key == BTN_OK){
//display_msg = DISP_REFRESH_ALL;
//display_msg = DSIP_END_SCORE;
return result;
}
return result;
}
Here is the main game function
void Game()
{
static int state;
int result;
switch (state)
{
case 1: //waiting for the game start
result = WaitForStart();
if (result == 1) state++;
break;
case 2: //Play the game
result = PlayTheGame();
if (result == 1) state++;
break;
case 3: //Display the score
result = EndOfGame();
if (result == 1) state=0;
break;
default: //0 or unknown value: reset the game
state = 1;
break;
}
}
Thanks.
I tried
int EndOfGame()
{
char key;
static int state;
int result = 1;
key = KBD_GetKey();
display_msg = DSIP_END_SCORE;
if (key == BTN_OK){
//display_msg = DISP_REFRESH_ALL;
//display_msg = DSIP_END_SCORE;
return result;
}
return result;
}
/*
display_msg = DSIP_END_SCORE;
if (key != 0){
switch (key)
{
case BTN_OK:
return result;
break;
}
}
*/
/*
switch (state)
{
case 0:
display_msg = DSIP_END_SCORE;
state++;
break;
case 1:
key = KBD_GetKey();
if (key != 0){
switch (key)
{
case BTN_OK:
return result;
break;
}
break;
}
}
return result;
*/
//display_msg = DISP_REFRESH_ALL;
//display_msg = DSIP_END_SCORE;
//return result;
/*
char key;
int result=0;
//static int state;
key = KBD_GetKey();
if (KBD_isKeyStatePressed(BTN_OK))
{
display_msg = DSIP_END_SCORE;
result = 1;
} else {
result = 1;
}
//return result;
*/
/*
switch (state){
case 0:
KBD_flush(); //empty buffer
//display_msg = DISP_REFRESH_ALL;
display_msg = DSIP_END_SCORE;
return result;
state++;
break;
case 1:
key = KBD_GetKey(); //kbd read dela background services
if (key == BTN_OK){
//display_msg = DISP_REFRESH_ALL;
display_msg = DSIP_END_SCORE;
return result;
break;
}
break;
}
return result;
*/
/*
key = KBD_GetKey();
if (key == BTN_OK) {
//display_msg = DISP_REFRESH_ALL;
return result;
}else{
display_msg = DISP_REFRESH_ALL;
display_msg = DSIP_END_SCORE;
//TODO: write the program
return result;
}*/
I found a solution!
Here is the code if anyone is interested.
int EndOfGame()
{
int result = 0;
char key;
static uint32_t timeStamp;
static int state = 0;
display_msg = DISP_REFRESH_ALL;
switch (state)
{
case 0: //Show end score
display_msg = DSIP_END_SCORE;
timeStamp = GetSysTick();
state++;
break;
case 1: //read keys after 2 seconds
if (Has_X_MillisecondsPassed(2000, &timeStamp)
{
state++;
KBD_flush();
break;
}
break;
case 2:
key = KBD_GetKey();
if (key != 0)
{
switch (key)
{
case BTN_OK:
state = 0;
result = 1;
break;
}
}
//finish after 10 seconds
if (Has_X_MillisecondsPassed(10000, &timeStamp))
{
result = 1;
state = 0;
break;
}
break;
}
return result;
}
If you want to know about the
Has_X_millisecondsPassed();
function you are welcome to see it in systime.c in the File list hyperlink in the question above. For the reference i'm using AtMega328pb microcontroller.

How to reduce the complexity of a GUI program

There is a problem confused me a lot.
I use C language to display GUI in the Embedded device.Just like the following example.
  title
1.xxxx 2.xxxx
3.xxxx 4.xxxx
5.xxxx 6.xxxx
I use the keypad to choose which item i need.but the item often has is's sub-item and I have to draw the menu and set the function again.Just like the follwing shows.
  title             title             title
1.xxxx 2.xxxx  press 1  1.xxxx 2.xxxx press 2   1.xxxx 2.xxxx
3.xxxx 4.xxxx --------------> 3.xxxx 4.xxxx --------------> 3.xxxx 4.xxxx
5.xxxx 6.xxxx       5.xxxx 6.xxxx       5.xxxx 6.xxxx
Now I use the following code temple to set the function i need.
GrawAndGetKeyCode( "0.xxxx||1.xxxx||2.xxxx||3.xxxx||4.xxxx", "title", &nSelect);
switch(nSelect)
{
case 0:
fuction();
break;
case 1:
fuction();
break;
case 2:
fuction();
break;
case 3:
fuction();
break;
case 4:
fuction();
break;
default:
break;
}
I wonder if there is some way i can use the menu1.item1.subitem2() to figure out the function i need?
Thanks a lot!!!
A simple menu system like that could be implemented using a simple state-machine.
Maybe something like this (warning: pseudo-ish code):
typedef void (*handler_t)(void); // Menu handler function type
handler_t * current_handlers;
char *current_menu;
// The top-level menu
handler_t top_menu_handlers[] = {
top_menu_1,
top_menu_2,
top_menu_3
};
char *top_menu = "..."; // Menu text for the top menu
// One sub-menu
handler_t sub_menu_1_handlers[] = {
sub_menu_1_1,
sub_menu_1_2,
sub_menu_1_3
};
char *sub_menu_1 = "...";
// Another sub-menu
handler_t sub_menu_2_handlers[] = {
sub_menu_2_1,
sub_menu_2_2,
sub_menu_2_3
};
char *sub_menu_2 = "...";
// ...
// Initialization
current_handlers = top_menu_handlers;
current_menu = top_menu;
// The state machine
for (;;) // Infinite loop
{
clear_screen();
print_menu(current_menu);
int selection = get_input();
current_handlers[selection](); // Call menu function
}
// ...
void top_menu_1(void)
{
// When user selects `1` in the top menu, go to first sub-menu
current_handlers = sub_menu_1_handlers;
current_menu = sub_menu_1;
}
// ...
void sub_menu_1_3(void)
{
// When the user select `3` in the first sub-menu, go back to top menu
current_handlers = top_menu_handlers;
current_menu = top_menu;
}
It's a lot of work to set up initially, but then it makes the code more general, and it's easier to add new alternatives or menus. And most importantly, it can be much more automated (by e.g. making the menu tree into an actual tree structure, and making the state-machine code handle the menu changing instead of having handler functions change it).
You may have a structure for menu items, each structure contains a label to be shown and a function pointer to be invoked. Then, your DrawMenuAndExecute function may take an array of menu_items and draw them, take the input and execute the corresponding function. Here is a working example:
#include <stdio.h>
#include <stdlib.h>
typedef void (* MENUFUNCPTR)();
struct menu_item {
const char *menu_item;
MENUFUNCPTR func;
};
void DrawMenuAndExecute(struct menu_item *items, size_t n) {
size_t i;
int opt;
int cont = 1;
// draw the menu
for (i = 0; i < n; ++i) {
printf("%3d: %s\n", (int)(i+1), items[i].menu_item);
}
printf("Your selection: ");
while (cont) {
scanf("%d", &opt);
if (opt > 0 && opt <= n) {
cont = 0;
}
else {
printf("Wrong selection, your selection again: ");
}
}
opt--;
if (items[opt].func != NULL) {
(*(items[opt].func))();
}
}
void main_menu();
void item1_item1();
void item1_item2();
void item1();
void item2();
void item3();
void item4();
void main_menu() {
struct menu_item items [] = {
{ "Item 1 (has submenu)", &item1 },
{ "Item 2 (count to ten)", &item2 },
{ "Item 3 (write something)", &item3 },
{ "Exit", &item4 }
};
DrawMenuAndExecute(items, 4);
}
void item1_item1() {
printf("Hello, how're you? (since I don't care, I won't let you type.)\n");
item1();
}
void item1_item2() {
main_menu();
}
void item1() {
// item1 has a sub menu
struct menu_item items [] = {
{ "Write something", &item1_item1 },
{ "Previous Menu", &item1_item2 }
};
DrawMenuAndExecute(items, 2);
}
void item2() {
int i = 1;
for (; i <= 10; ++i) {
printf("%d ", i);
}
printf("\n");
main_menu();
}
void item3() {
printf("Something.\n");
main_menu();
}
void item4() {
exit(0);
}
int main(int argc, char **argv) {
main_menu();
}

Resources