stdarg
33 отговора
834 прегледа
stdarg
Здравейте,
трябва да направя функция която да приема променлив брой аргументи (по точно низове). Зачетох се в "ръководството" за stdarg.h и ми стана ясно как да го направя... обаче се оказа че часта:
case 's': .... /* string */
не работи .... След като потърсих с google отговор на въпроса се оказа че почти навсякъде се пише само за случаи 'i' и 'd' (int, double), а на мен ми трябва точно за низове...
Ще се раздвам ако някой може да ми помогне.
трябва да направя функция която да приема променлив брой аргументи (по точно низове). Зачетох се в "ръководството" за stdarg.h и ми стана ясно как да го направя... обаче се оказа че часта:
case 's': .... /* string */
не работи .... След като потърсих с google отговор на въпроса се оказа че почти навсякъде се пише само за случаи 'i' и 'd' (int, double), а на мен ми трябва точно за низове...
Ще се раздвам ако някой може да ми помогне.
Re: stdarg
switch работи само със целочислени типове и приравнените на тях.
// доколкото знам - май в C# може case-ове да са и стрингове, но не съм
сигурен...
а не би ли трябвало да прихващаш променливия брой параметри, които са стрингове като указатели към низове ?
най-често умните хора са и лоши
// доколкото знам - май в C# може case-ове да са и стрингове, но не съм
сигурен...
а не би ли трябвало да прихващаш променливия брой параметри, които са стрингове като указатели към низове ?
най-често умните хора са и лоши
Re: stdarg
Ok, ето го:
va_list ap;
va_start (ap, fmt);
menu = gtk_menu_new ();
while (*fmt) {
switch (*fmt++) {
case 's':
menu_item = gtk_menu_item_new_with_label ( va_arg(ap, gchar *) );
gtk_menu_shell_append ( GTK_MENU_SHELL (menu), menu_item);
g_signal_connect_swapped (G_OBJECT (menu_item), "activate",
G_CALLBACK (action),
(gpointer) 1 );
gtk_widget_show ( menu_item );
break;
}
va_end (ap);
"Принципа на действие" е едно към едно направен както е обяснено за работа с stdarg ....
Нищо от посочения по горе case не се изпълнява. Разбира се, мога да го направя и по друг начин, но ме интересува защо този не работи.
va_list ap;
va_start (ap, fmt);
menu = gtk_menu_new ();
while (*fmt) {
switch (*fmt++) {
case 's':
menu_item = gtk_menu_item_new_with_label ( va_arg(ap, gchar *) );
gtk_menu_shell_append ( GTK_MENU_SHELL (menu), menu_item);
g_signal_connect_swapped (G_OBJECT (menu_item), "activate",
G_CALLBACK (action),
(gpointer) 1 );
gtk_widget_show ( menu_item );
break;
}
va_end (ap);
"Принципа на действие" е едно към едно направен както е обяснено за работа с stdarg ....
Нищо от посочения по горе case не се изпълнява. Разбира се, мога да го направя и по друг начин, но ме интересува защо този не работи.
Re: stdarg
's' e char
"s" e string
ako iskash da sravniavash stringove izpolzvai strcmp()
"s" e string
ako iskash da sravniavash stringove izpolzvai strcmp()
Re: stdarg
Можеше да постнеш и декларацията на функцията все пак... Приемам, че fmt е char*...
Та, в случая, този "case 's'" трябва да си работи - 's' е от тип char, а char-овете могат да бъдат параметри на switch, никакви проблеми няма. Но това какво общо има със <stdarg.h>?
Та, в случая, този "case 's'" трябва да си работи - 's' е от тип char, а char-овете могат да бъдат параметри на switch, никакви проблеми няма. Но това какво общо има със <stdarg.h>?
Нещо не си ме разбрал...
Нямам проблем със сравняването на стрингове и char -ове. Става дума че в man страницата е описано че трябва така да се направи, но това не работи .....
Ето ти директно примера от man страницата, за потвърждение:
--------------------------------------------------
EXAMPLES
The function foo takes a string of format characters and prints out the
argument associated with each format character based on the type.
#include <stdio.h>
#include <stdarg.h>
void foo(char *fmt, ...) {
va_list ap;
int d;
char c, *p, *s;
va_start(ap, fmt);
while (*fmt)
switch(*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
-----------
Ето ти директно примера от man страницата, за потвърждение:
--------------------------------------------------
EXAMPLES
The function foo takes a string of format characters and prints out the
argument associated with each format character based on the type.
#include <stdio.h>
#include <stdarg.h>
void foo(char *fmt, ...) {
va_list ap;
int d;
char c, *p, *s;
va_start(ap, fmt);
while (*fmt)
switch(*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
-----------
декларацията....
void add_menu ( GtkWidget *menu_bar, gint y, char *fmt, ... );
В случая не мисля че декларацията има нещо общо.
В случая не мисля че декларацията има нещо общо.
Re: stdarg
teb jasna li ti e ideata za kakvo sluji stdarg ? znaesh li kakvo izkash da napravish ?
kakvo podavash v stringa "fmt". tvoja code predpolaga 4e v tozi string triabva da podadesh tipa na argumentite, primerno:
void foo(char* fmt,...);
foo("sdc","string",5,'c'); -> podavsh string, int, char
foo("cd",'f',66); -> podavash char, int
foo("ssds","s1","s2",5,"s4"); -> sam se seti kvo podavsah :)
man ne si razbral suvsem man stranicata :)
kakvo podavash v stringa "fmt". tvoja code predpolaga 4e v tozi string triabva da podadesh tipa na argumentite, primerno:
void foo(char* fmt,...);
foo("sdc","string",5,'c'); -> podavsh string, int, char
foo("cd",'f',66); -> podavash char, int
foo("ssds","s1","s2",5,"s4"); -> sam se seti kvo podavsah :)
man ne si razbral suvsem man stranicata :)
Ееххх, аман от акалии
Много добре съм прочел и разбрал man страницата. В моя случай на мен ми е предварително известно че от едно място на там се предават само низове.
И да ти отговоря - да много добре знам какво искам да направя. Абе тука ще се намери ли един човек който да може да ми отговори? Писнало ми е от някакви детски изказвания.
Нищо де, сам съм си виновен - предупредиха ме че тук няма да намеря много адекватни мнения. Ще се радвам ако модератора заключи темата или направо я изтрие.
По живо по здраво си останете "програмисти".
И да ти отговоря - да много добре знам какво искам да направя. Абе тука ще се намери ли един човек който да може да ми отговори? Писнало ми е от някакви детски изказвания.
Нищо де, сам съм си виновен - предупредиха ме че тук няма да намеря много адекватни мнения. Ще се радвам ако модератора заключи темата или направо я изтрие.
По живо по здраво си останете "програмисти".
Re: Ееххх, аман от акалии
Виж, при начина, по който си задал въпроса си, не очаквай по-смислени отговори. Най-малкото, не си личи да разбираш за какво става дума. Казваш че кода от man-страницата не работел, обаче той си работи чудесно.
Аз лично не разбрах кое точно смяташ че не ти работи, ако го обясниш като за бели хора може и да ти отговорим като такива.
Аз лично не разбрах кое точно смяташ че не ти работи, ако го обясниш като за бели хора може и да ти отговорим като такива.
Re: Ееххх, аман от акалии
Ок, ще се опитам да обясня - афектирах се много от по горно мнение.
Имам финкция (прототипа показах по горе) която от N -тия аргумент натам може да получи неизвестен брой аргументи. Както казах по рано, правя функцията както е по ръководствата, като използвам само часта за низове, защото само тя ме интересува и съм сигурен че ще са само низове (защото аз ще подавам аргументите). Там е работата, че това по този начин неработи !
Аз го направих да ми върши работа - просто не използвам switch/case защото съм сигурен че неизвестният брой аргументи са низове.
Въпроса ми е защо не работи като се използва switch ... case 's' ?
Разните отговори от рода - това е знак, онова е низ, изобщо не и ми вършат работа.
Преди да питам тук съм се ровил доста.
Имам финкция (прототипа показах по горе) която от N -тия аргумент натам може да получи неизвестен брой аргументи. Както казах по рано, правя функцията както е по ръководствата, като използвам само часта за низове, защото само тя ме интересува и съм сигурен че ще са само низове (защото аз ще подавам аргументите). Там е работата, че това по този начин неработи !
Аз го направих да ми върши работа - просто не използвам switch/case защото съм сигурен че неизвестният брой аргументи са низове.
Въпроса ми е защо не работи като се използва switch ... case 's' ?
Разните отговори от рода - това е знак, онова е низ, изобщо не и ми вършат работа.
Преди да питам тук съм се ровил доста.
Re: Ееххх, аман от акалии
Kyde ti e src na samata funkcia? Kak ia wikash? Kakwo stawa? Koe ne raboti? Tuka niakoi da ti prilicha na baba Vanga?
Re: по горе
Ей този ред като го гледам:
menu_item = gtk_menu_item_new_with_label ( va_arg(ap, gchar *) );
Значи, параметрите които получаваш, са "char *". Не съм наясно с хедърите на GTK-то, но сигурен ли си че това "gchar *" е еквивалентно на "char *"? Тоест, дали gchar == char? Ако примерно gchar всъщност е wide char (2 байта), логично е да не става.
Edit: Всъщност получаваш "const char *", ама все тая...
menu_item = gtk_menu_item_new_with_label ( va_arg(ap, gchar *) );
Значи, параметрите които получаваш, са "char *". Не съм наясно с хедърите на GTK-то, но сигурен ли си че това "gchar *" е еквивалентно на "char *"? Тоест, дали gchar == char? Ако примерно gchar всъщност е wide char (2 байта), логично е да не става.
Edit: Всъщност получаваш "const char *", ама все тая...
Редактирано от Pesho® на
Re: по горе
В документацията на GTK пише че gchar == char, guchar == unsigned char и т.н.
Преди да пиша тук бях пробвал и само с char - положението е същото.
Преди да пиша тук бях пробвал и само с char - положението е същото.
Re: по горе
Дай още инфо - с какви параметри викаш add_menu(), какво би трябвало да се случи ако работи, и какво се случва в действителност?
Re: по горе
В идеалният случай (ако всичко работи както се очаква), add_menu се извиква с първи аргумент указател към GtkWidget обект, в случая menu_bar. Следващите аргументи са низове, като първият от тях е името на менюто.
В текущия случай, като втори аргумент на функцията предавам броя на елементите в менюто (без името му).
И в двата случая, крайният резултат е създаване на меню с име първият низов аргумент и елементи останалите низови аргументи, и добавяне на това меню към menu_bar (първият аргумент на add_menu).
В момента е "действащ" втория вариант (в смисъл работи и се постига желания ефект) но така се губи наполовина идеята за неопределния брой аргументи.... и точно това ме притеснява - не че може да ми трябва точно за това което правя в момента, но в бъдеще може да ми се наложи да правя такава функция и предпочитам от сега да знам къде е проблема
В текущия случай, като втори аргумент на функцията предавам броя на елементите в менюто (без името му).
И в двата случая, крайният резултат е създаване на меню с име първият низов аргумент и елементи останалите низови аргументи, и добавяне на това меню към menu_bar (първият аргумент на add_menu).
В момента е "действащ" втория вариант (в смисъл работи и се постига желания ефект) но така се губи наполовина идеята за неопределния брой аргументи.... и точно това ме притеснява - не че може да ми трябва точно за това което правя в момента, но в бъдеще може да ми се наложи да правя такава функция и предпочитам от сега да знам къде е проблема
Re: stdarg
dobre mai nishto niama da widia taka :)
moje li da debugnesh ili da printwash
fmt w predi cikyla
i stoinostite na *fmt po wrene na izpylnenieto na tozi
cikyl - while(*fmt)
mislia che towa shte oswetli nehstata...
moje li da debugnesh ili da printwash
fmt w predi cikyla
i stoinostite na *fmt po wrene na izpylnenieto na tozi
cikyl - while(*fmt)
mislia che towa shte oswetli nehstata...
:)))
верно отговорите не бяха много компетентни:)
е, и аз не мога да дам компетентен отговор, но поне няма да ти кажа че 's' не било стринг (ха ха) а било символ.
сега малко по-конструктивно. ти пробва ли да дебъгваш? видя ли какъв ти е стринга с форматиращите символи? защото не ми се вярва да са останали всички букви освен s... значи според мен получаваш неверен форматиращ стринг. виж го при дебъг и евентуално виж къде се губи. толкова мога да предложа.
е, и аз не мога да дам компетентен отговор, но поне няма да ти кажа че 's' не било стринг (ха ха) а било символ.
сега малко по-конструктивно. ти пробва ли да дебъгваш? видя ли какъв ти е стринга с форматиращите символи? защото не ми се вярва да са останали всички букви освен s... значи според мен получаваш неверен форматиращ стринг. виж го при дебъг и евентуално виж къде се губи. толкова мога да предложа.