a c question

Programming, for all ages and all languages.
Schol-R-LEA

Re:a c question

Post 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.
Schol-R-LEA

Re:a c question

Post 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.
Schol-R-LEA

Re:a c question

Post 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.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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);
}
Only Human
Schol-R-LEA

Re:a c question

Post 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.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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???
Only Human
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a c question

Post 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();
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post by Neo »

Nope that doesn't work either. I tried calling the clrscr() function with it and nothing happened.
Any other ideas????
Only Human
Joel (not logged in)

Re:a c question

Post 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();
}
Joel (not logged in)

Re:a c question

Post by Joel (not logged in) »

and, of course, return a value from main after declaring it as an int. ::)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a c question

Post 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
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post by Neo »

Works like a charm. thanks guys.
Only Human
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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?
Only Human
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a c question

Post 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?
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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?
Only Human
Post Reply