stdarg

33 отговора 834 прегледа
#1

stdarg

Здравейте,
трябва да направя функция която да приема променлив брой аргументи (по точно низове). Зачетох се в "ръководството" за stdarg.h и ми стана ясно как да го направя... обаче се оказа че часта:

case 's': .... /* string */

не работи .... След като потърсих с google отговор на въпроса се оказа че почти навсякъде се пише само за случаи 'i' и 'd' (int, double), а на мен ми трябва точно за низове...

Ще се раздвам ако някой може да ми помогне.

Отговор
в отговор на some #2

Re: stdarg

switch работи само със целочислени типове и приравнените на тях.
// доколкото знам - май в C# може case-ове да са и стрингове, но не съм
сигурен...

а не би ли трябвало да прихващаш променливия брой параметри, които са стрингове като указатели към низове ?

най-често умните хора са и лоши
Отговор
в отговор на some #3

Re: stdarg

kyf string?
ia go napishi towa deto ne raboti

Отговор
в отговор на odce #4

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 не се изпълнява. Разбира се, мога да го направя и по друг начин, но ме интересува защо този не работи.

Отговор
в отговор на some #5

Re: stdarg

's' e char
"s" e string

ako iskash da sravniavash stringove izpolzvai strcmp()

Отговор
в отговор на some #6

Re: stdarg

Можеше да постнеш и декларацията на функцията все пак... Приемам, че fmt е char*...

Та, в случая, този "case 's'" трябва да си работи - 's' е от тип char, а char-овете могат да бъдат параметри на switch, никакви проблеми няма. Но това какво общо има със <stdarg.h>?

Отговор
в отговор на shoro #7

Нещо не си ме разбрал...

Нямам проблем със сравняването на стрингове и 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);
}

-----------

Отговор
в отговор на Pesho® #8

декларацията....

void add_menu ( GtkWidget *menu_bar, gint y, char *fmt, ... );

В случая не мисля че декларацията има нещо общо.

Отговор
в отговор на some #9

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 :)

Отговор
в отговор на arg #10

Ееххх, аман от акалии

Много добре съм прочел и разбрал man страницата. В моя случай на мен ми е предварително известно че от едно място на там се предават само низове.

И да ти отговоря - да много добре знам какво искам да направя. Абе тука ще се намери ли един човек който да може да ми отговори? Писнало ми е от някакви детски изказвания.

Нищо де, сам съм си виновен - предупредиха ме че тук няма да намеря много адекватни мнения. Ще се радвам ако модератора заключи темата или направо я изтрие.
По живо по здраво си останете "програмисти".

Отговор
в отговор на some #11

Re: Ееххх, аман от акалии

Виж, при начина, по който си задал въпроса си, не очаквай по-смислени отговори. Най-малкото, не си личи да разбираш за какво става дума. Казваш че кода от man-страницата не работел, обаче той си работи чудесно.

Аз лично не разбрах кое точно смяташ че не ти работи, ако го обясниш като за бели хора може и да ти отговорим като такива.

Отговор
в отговор на Pesho® #12

Re: Ееххх, аман от акалии

Ок, ще се опитам да обясня - афектирах се много от по горно мнение.

Имам финкция (прототипа показах по горе) която от N -тия аргумент натам може да получи неизвестен брой аргументи. Както казах по рано, правя функцията както е по ръководствата, като използвам само часта за низове, защото само тя ме интересува и съм сигурен че ще са само низове (защото аз ще подавам аргументите). Там е работата, че това по този начин неработи !
Аз го направих да ми върши работа - просто не използвам switch/case защото съм сигурен че неизвестният брой аргументи са низове.

Въпроса ми е защо не работи като се използва switch ... case 's' ?
Разните отговори от рода - това е знак, онова е низ, изобщо не и ми вършат работа.

Преди да питам тук съм се ровил доста.

Отговор
в отговор на some #13

Re: Ееххх, аман от акалии

Kyde ti e src na samata funkcia? Kak ia wikash? Kakwo stawa? Koe ne raboti? Tuka niakoi da ti prilicha na baba Vanga?

Отговор
в отговор на gruhal #14

по горе

И "src" -то и прототипа на функцията съм ги написал по горе.

Отговор
в отговор на some #15

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 *", ама все тая...

Редактирано от Pesho® на

Отговор
в отговор на Pesho® #16

Re: по горе

В документацията на GTK пише че gchar == char, guchar == unsigned char и т.н.
Преди да пиша тук бях пробвал и само с char - положението е същото.

Отговор
в отговор на some #17

Re: по горе

Дай още инфо - с какви параметри викаш add_menu(), какво би трябвало да се случи ако работи, и какво се случва в действителност?

Отговор
в отговор на Pesho® #18

Re: по горе

В идеалният случай (ако всичко работи както се очаква), add_menu се извиква с първи аргумент указател към GtkWidget обект, в случая menu_bar. Следващите аргументи са низове, като първият от тях е името на менюто.
В текущия случай, като втори аргумент на функцията предавам броя на елементите в менюто (без името му).
И в двата случая, крайният резултат е създаване на меню с име първият низов аргумент и елементи останалите низови аргументи, и добавяне на това меню към menu_bar (първият аргумент на add_menu).

В момента е "действащ" втория вариант (в смисъл работи и се постига желания ефект) но така се губи наполовина идеята за неопределния брой аргументи.... и точно това ме притеснява - не че може да ми трябва точно за това което правя в момента, но в бъдеще може да ми се наложи да правя такава функция и предпочитам от сега да знам къде е проблема

Отговор
в отговор на some #19

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...

Отговор
в отговор на some #20

:)))

верно отговорите не бяха много компетентни:)
е, и аз не мога да дам компетентен отговор, но поне няма да ти кажа че 's' не било стринг (ха ха) а било символ.
сега малко по-конструктивно. ти пробва ли да дебъгваш? видя ли какъв ти е стринга с форматиращите символи? защото не ми се вярва да са останали всички букви освен s... значи според мен получаваш неверен форматиращ стринг. виж го при дебъг и евентуално виж къде се губи. толкова мога да предложа.

Отговор