Page 3 of 5
Re:a c question
Posted: Sat Feb 07, 2004 4:59 pm
by Schol-R-LEA
The sort of pointer you want to use isn't the issue, as demonstrated by this program:
Code: Select all
#include <stdio.h>
struct {
int bar, baz, qux;
} foo;
main()
{
foo.bar = 0;
foo.baz = 0;
foo.qux = 0;
scanf("%d", &foo.bar);
printf("%d\n", foo.bar);
scanf("%d", &(foo).baz);
printf("%d\n", foo.baz);
scanf("%d", &(foo.qux));
printf("%d\n", foo.qux);
}
This runs under both Dev-C++ 4.98 and Visual C++ 6.0 without a problem.
The problem looks to be with the scanf() and printf format strings; you are using it to fill and print chars, but you are using the formatting code for integers (%d). You will need to use %c instead. The lack of typechecking in these two functions, while occasionally useful, is a serious problem in using them. Here's a modified version of the code below, with a few changes to make it easier to work with:
Code: Select all
#include <stdio.h>
typedef struct{
char sec;
char min;
char hr;
int day;
} time;
time addtime(time t1,time t2)
{
time op;
op.min=0;
op.hr=0;
op.sec = t1.sec + t2.sec;
if(op.sec>59){
op.sec %= 60;
op.min++;
}
op.min += t1.min + t2.min;
if(op.min>59){
op.min %= 60;
op.hr++;
}
op.hr += t1.hr + t2.hr;
return op;
}
main()
{
time op,tim1,tim2;
/* initializing op */
op.hr = '0';
op.sec = '0';
op.min = '0';
printf("initial time: \n%c:%c:%c\n",op.hr,op.min,op.sec);
tim1.sec=40; tim1.min=15; tim1.hr=11;
fflush(stdin);
puts("Hour: ");
scanf("%c", &tim2.hr);
fflush(stdin);
puts("Minute: ");
fflush(stdin);
scanf("%c", &tim2.min);
fflush(stdin);
puts("Second: ");
scanf("%c", &tim2.sec);
printf("\nTime2= %c:%c:%c",tim2.hr,tim2.min,tim2.sec);
op=addtime(tim1,tim2);
printf("Corrected Time: \n%c:%c:%c",op.hr,op.min,op.sec);
getch();
}
(BTW, always remember to include any headers you need; while C is rather tolerant of it, having them can help avoid a lot of problems; such as mismatched argument types).
This reads and prints the data correctly, though the addtime function still needs work, it seems. HTH.
Re:a c question
Posted: Sat Feb 07, 2004 5:38 pm
by Schol-R-LEA
Oh, and I might add: you might want to change those variables from single chars to char[3] or larger (in which case the format string will have to use '%s'). As it is now, you can only have one digit for each of them; a three char array would give you room for two digits and a string delimiter.
Re:a c question
Posted: Mon Feb 09, 2004 2:44 am
by Schol-R-LEA
Taking a quick look at the addtime() function, the problem is clear: you are using the char variables as if they were ints, which I gather they originally were.
Re:a c question
Posted: Mon Feb 09, 2004 11:34 am
by Neo
I'm not sure about that but i use GCC in windows and after including the stdio.h file like you said the thing worked perfectly.Here's the code
Code: Select all
#include<stdio.h>
typedef struct{
???int ???sec;
???int???min;
???int???hr;
???unsigned long???day;
} time_s;
time_s sec2time(unsigned long seconds)
{
???time_s time;
???time.sec = seconds%60;
???seconds /= 60;
???time.min = seconds%60;
???seconds /= 60;
???time.hr = seconds%24;
???time.day = seconds/24;
???return time;
}
time_s addtime(time_s t1,time_s t2)
{
???time_s op;
???op.min=0;
???op.hr=0;
???op.sec = t1.sec + t2.sec;
???if(op.sec>59){
??? ???op.sec %= 60;
??????op.min++;
???}
???op.min += t1.min + t2.min;
???if(op.min>59){
??????op.min %= 60;
??????op.hr++;
???}
???op.hr += t1.hr + t2.hr;
???return op;
}
int main()
{
???time_s boot,now,op;
???unsigned long sec;
???boot.sec=40;
???boot.min=15;
???boot.hr=11;
???printf("Enter First Hr:Min:Sec");
???scanf("%d%d%d",&boot.hr,&boot.min,&boot.sec);
???printf("Enter Second Hr:Min:Sec");
???scanf("%d%d%d",&now.hr,&now.min,&now.sec);
???op=addtime(boot,now);
???printf("\n%d:%d:%d",op.hr,op.min,op.sec);
???printf("Enter Seconds :");
???scanf("%d",&sec);
???time_s t=sec2time(sec);
???printf("\nIn Time= %u:%u:%u:%u",t.day,t.hr,t.min,t.sec);
}
Re:a c question
Posted: Mon Feb 09, 2004 12:12 pm
by Schol-R-LEA
OK, changing the chars to ints works too
I didn't want to suggest it, since I thought you might have had some particular reason to use chars.
Oh, you might still want to fflush(stdin) after each scanf() call, in case someone puts too many numbers in by accident.
Re:a c question
Posted: Mon Mar 15, 2004 9:33 pm
by Neo
Ok another C question now. I know that you can use functions in structures along with variables. but how do you call these functions which are members of the structure. For e.g. if i have a structure as
Code: Select all
typedef struct{
char *str;
void *func;
} FUNCTION;
and i use this in my code
Code: Select all
FUNCTION f1;
f1.str="something";
f1.func=(void*)(somefunc());
what i want to do is call function 'somefunc()' using the structure vr 'f1'. i tried using
but got nothing. So how do i call this function???
Re:a c question
Posted: Tue Mar 16, 2004 2:39 am
by Candy
Neo wrote:
what i want to do is call function 'somefunc()' using the structure vr 'f1'. i tried using
but got nothing. So how do i call this function???
As a function:
Re:a c question
Posted: Tue Mar 16, 2004 12:56 pm
by Neo
Nope that doesn't work either. I tried calling the clrscr() function with it and nothing happened.
Any other ideas????
Re:a c question
Posted: Tue Mar 16, 2004 1:02 pm
by Joel (not logged in)
You have to declare the function pointer along with its return and argument types:
Code: Select all
typedef struct
{
char* str;
void (*func) ();
} FUNCTION;
Then call the function like this:
Code: Select all
void doNothing()
{
}
int main()
{
FUNCTION f1;
f1.str = "Whatever";
f1.func = doNothing;
f1.func();
}
Re:a c question
Posted: Tue Mar 16, 2004 1:04 pm
by Joel (not logged in)
and, of course, return a value from main after declaring it as an int. ::)
Re:a c question
Posted: Tue Mar 16, 2004 1:09 pm
by Candy
*ugh* sees the UGLY problem...
you want a function pointer. Take the address of the function.
Code: Select all
void (*function)();
function = &clrscr;
Notably, do NOT place ()'s after the function. You don't want to call it.
GL
Re:a c question
Posted: Tue Mar 16, 2004 1:45 pm
by Neo
Works like a charm. thanks guys.
Re:a c question
Posted: Wed Mar 17, 2004 1:24 pm
by Neo
Now if i want to pass arguments and get return values with those functions what should i do?
btw if i have different functions with different type/no. of args and different return types etc can i use the same structure?
Re:a c question
Posted: Wed Mar 17, 2004 1:45 pm
by Candy
Neo wrote:
Now if i want to pass arguments and get return values with those functions what should i do?
btw if i have different functions with different type/no. of args and different return types etc can i use the same structure?
Arguments:
Code: Select all
struct something {
int something;
void (*function)(uintn arg1, char *arg2, some_weird_type arg3);
}
void func(uintn, char *, some_weird_type);
void reg() {
struct something.function = &func;
something.function(1, a, structthingy);
}
return type:
Code: Select all
char *(*function)(args);
char *stringy = struct.function(args);
PS, tried checking a book or the web on function pointers?
Re:a c question
Posted: Thu Mar 25, 2004 1:00 pm
by Neo
i was thinking of writing my own "stdarg" file and wanted to get a few things clear
1) do we declare va_list as a char* or void* ? void* seems more generic but i think char* would permit pointer arithmetic without warnings.
2) what exactly does va_end() do? I could find no info other than the explantion that "it must be called once after processing" and that "it does cleanup"
3) i also saw that the linux src uses "rounded off" sizes for all datatypes. does this have to be done or can we just add the value
to the arg pointer?