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

Code: Select all

f1.func;
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

Code: Select all

f1.func;
but got nothing. So how do i call this function???
As a function:

Code: Select all

f1.func();

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

Code: Select all

sizeof(datatype)
to the arg pointer?