mcintyre@turing.cs.rpi.edu (David McIntyre) (01/14/89)
I am having a little trouble with C, and am hoping that someone has already conquered this problem: I am using _dos_findfirst and _dos_findnext to get information about directory entries. The time and date stamps on the file are returned as unsigneds (wr_time and wr_date). I would like to extract the information about date and time from these unsigneds, but the time and date conversion functions do not seem to take similar values. Could someone give me 2 or 3 sample lines of code showing how to print these unsigned dates and times as xx:xx:xx and xx/xx/xxxx values? Thanks, Dave Dave "mr question" McIntyre | "....say you're thinking about a plate mcintyre@turing.cs.rpi.edu | of shrimp.....and someone says to office : 518-276-8633 | you `plate,' or `shrimp'......" home : 518-271-6664 |
furlani@broadway.UUCP (John L. Furlani) (01/15/89)
In article <104@rpi.edu>, mcintyre@turing.cs.rpi.edu (David McIntyre) writes: > > Could someone give me 2 or 3 sample lines of code showing > how to print these unsigned dates and times as xx:xx:xx and xx/xx/xxxx > values? > Here are two functions that do just that when passed the date and time, respectively. It should be noted that since DOS stores file times acurate only to 2 second intervals, seconds are usually left off. I recommend looking into purchasing The Waite Group's Microsoft C Bible. It has all the 5.1 functions will full usage, compatability, example codes, other book references for more information on a particular subject, and more. I hope these help. print_sysdate (int date) { unsigned day = (date & 0x1f); unsigned month = (date >> 5) & 0xf; unsigned year = (date >> 9) & 0x7f; printf("%2d/%2d/%2d", day, month, (year + 80)); } print_systime(int time) { char min_str[5]; char sec_str[5]; unsigned second = (time & 0x1f) * 2; unsigned minute = (time >> 5) & 0x3f; unsigned hour = (time >> 11) & 0x1f; if(minute < 10) sprintf(min_str, "0%d", minute); else sprintf(min_str, "%d", minute); if(second < 10) sprintf(sec_str, "0%d", second); else sprintf(sec_str, "%d", second); printf("%2d:%s:%s", hour, min_str, sec_str); } ____________ Disclaimer: "Just blame Me, Myself, and I for it." John L. Furlani The University of South Carolina, Columbia SC (...!uunet!ncrlnk!ncrcae!broadway!furlani)
ka@june.cs.washington.edu (Kenneth Almquist) (01/16/89)
] if(minute < 10) ] sprintf(min_str, "0%d", minute); ] else ] sprintf(min_str, "%d", minute); ] ] if(second < 10) ] sprintf(sec_str, "0%d", second); ] else ] sprintf(sec_str, "%d", second); ] ] printf("%2d:%s:%s", hour, min_str, sec_str); This can be shortened to printf("%2d:%.2d:%.2d", hour, minute, second); A "." introduces a precision, which specifies the minimum number of digits to print. Kenneth Almquist
abcscnge@csuna.UUCP (Scott "The Pseudo-Hacker" Neugroschl) (01/22/89)
In article <6951@june.cs.washington.edu> ka@june.cs.washington.edu (Kenneth Almquist) writes:
]] if(minute < 10)
]] sprintf(min_str, "0%d", minute);
]] else
]] sprintf(min_str, "%d", minute);
]]
]] if(second < 10)
]] sprintf(sec_str, "0%d", second);
]] else
]] sprintf(sec_str, "%d", second);
]]
]] printf("%2d:%s:%s", hour, min_str, sec_str);
]
]This can be shortened to
]
] printf("%2d:%.2d:%.2d", hour, minute, second);
]
] Kenneth Almquist
How about
printf("%2d:%02d:%02d", hour, minute, second);
K&R (page 146) specify that the 0 is the pad character to pad out the
2 digit integer in this case. Seems to solve all the problems.
--
Scott "The Pseudo-Hacker" Neugroschl
UUCP: ...!sm.unisys.com!csun!csuna!abcscnge
-- "Beat me, whip me, make me code in Ada"
-- Disclaimers? We don't need no stinking disclaimers!!!
ka@june.cs.washington.edu (Kenneth Almquist) (01/22/89)
abcscnge@csuna.UUCP (Scott "The Pseudo-Hacker" Neugroschl) writes: > In article <6951@june.cs.washington.edu> ka@june.cs.washington.edu (Kenneth Almquist) writes: > ] printf("%2d:%.2d:%.2d", hour, minute, second); > > How about > printf("%2d:%02d:%02d", hour, minute, second); These behave identically. A fair number of years ago, AT&T decided to switch from the "%02d" format to the "%.2d" format. A couple of reasons for this may be: 1) Conceptual simplicity. The printf format has a precision field for use by the %s and the floating point formats; it makes sense to use this same field for integer formats rather than ignoring the precision and using some other method of getting zero padding. 2) Flexibility. Using the precision to specify the zero padding allows the field width to be used for its normal function even when zero padding is desired. The "%02d" format will no doubt continue to work forever. I've switched to the new format because I don't expect newcomers to the C world want to learn all the obsolete features of the language. Kenneth Almquist
ark@alice.UUCP (Andrew Koenig) (01/23/89)
In article <7026@june.cs.washington.edu>, ka@june.cs.washington.edu (Kenneth Almquist) writes: > abcscnge@csuna.UUCP (Scott "The Pseudo-Hacker" Neugroschl) writes: > > In article <6951@june.cs.washington.edu> ka@june.cs.washington.edu (Kenneth Almquist) writes: > > ] printf("%2d:%.2d:%.2d", hour, minute, second); > > > > How about > > printf("%2d:%02d:%02d", hour, minute, second); > > These behave identically. A fair number of years ago, AT&T decided to > switch from the "%02d" format to the "%.2d" format. Actually, they behave identically only for positive numbers. The change came about for several reasons, not all of which I remember. One was a desire to be able to print things like 0x00076552, which just didn't fit into the notion of zero-padding. Another was that `zero-padding' didn't really describe the operation. After all, if you zero-pad -3 to six characters, you should get 0000-3, right? Some head-scratching and a lot of discussion later, we decided that the operation we really wanted was `guarantee at least a particular number of digits' and that that should be done as part of conversion, not as part of padding. -- --Andrew Koenig ark@europa.att.com
mfinegan@uceng.UC.EDU (michael k finegan) (01/26/89)
I have been having a problem with far pointer conversion in MSC 5.1, using the medium memory model. It goes like this: in medium model code pointers are 32 bits, while data pointers are 16 bits. There is an exception to the data pointer size, and that is done using the keyword far. What I am trying to do is put an address into a far data pointer (unsigned char far * ptr), which works okay at first, but when the global pointer gets accessed in a subroutine, low and behold - it is different! It appears that the high order word is zeroed out ... My question: has anyone out there in net land put addresses into far pointers in medium model with success? Is there a trick? The people at MSC claim it should work, but they haven't tried to code it ... (By the way - I am using buildptr(segment,offset) from the LIM specs. to instantiate the pointers: the far pointer is treated as an unsigned long, and the segment is shifted left 16 and added to the offset to create the far ptr) Thanks, Mike Finegan mfinegan@uceng.uc.edu
seg@smsdpg.uu.net (Scott Garfinkle) (01/27/89)
From article <617@uceng.UC.EDU>, by mfinegan@uceng.UC.EDU (michael k finegan): > What I am trying to do is put an address into a far data pointer > (unsigned char far * ptr), which works okay at first, but when the global > pointer gets accessed in a subroutine, low and behold - it is different! It > appears that the high order word is zeroed out ... My question: has anyone out > there in net land put addresses into far pointers in medium model with success? > Is there a trick? No. I've done it. It works. It's just a real pain. Following code to set an arbitrary string in the DOS environment works in all models: Scott E. Garfinkle SMS Data Products Group, Inc. uunet!smsdpg!seg (seg@smsdpg.uu.net) ---------- /* Demo of how to set a string in parent environment. * By Scott E. Garfinkle -- No rights reserved, no responsibility assumed. * * This program can be very unhealthy for your environment. In particular, * it does not do the following: * 1. Check for theoretically illegal characters, like '=' in the * environment. * 2. Remove old definitions that you're redefining. * 3. Check to see if you've hit the limit of the environment size. * 4. Force the new variable into uppercase. * Some of the above aren't bugs, depending on your point of view. If you * don't like something, change it. */ #include <stdio.h> extern unsigned _psp; /* set to segment of our psp by MSC init routines */ /* from dos.h */ #define FP_SEG(fp) (*((unsigned *)&(fp) + 1)) #define FP_OFF(fp) (*((unsigned *)&(fp))) main(int argc, char **argv) { char far *env_ptr; int count; unsigned far *psp_ptr; extern char *getenv(const char *); if(argc != 3) { fprintf(stderr,"Usage: %s <variable> <value>\n", *argv); exit(1); } psp_ptr = (unsigned far *) (((long) _psp << 16 ) + 0x16L); /* now psp_ptr points to DOS PSP segment */ psp_ptr = (unsigned far *) (((long) *psp_ptr << 16 ) + 0x2cL); /* now psp_ptr points to DOS environ segment */ env_ptr = (char far *) ((long) *psp_ptr << 16 ); /* now env_ptr points to DOS environ */ while(*env_ptr) /* skip past the current strings */ env_ptr += strlen(env_ptr)+1; /* usually, sprintf returns number of characters written, excluding * the null. This is true, e.g. for msc. */ #ifndef SPRINTF_RETURNS_CHAR { int count; char buffer[512]; /* arbitrary */ count = sprintf(buffer,"%s=%s",argv[1],argv[2]); movedata( /* of course microsoft does this backwards */ (unsigned) (( (long) (char far *) buffer) >> 16), /* yech */ (unsigned) buffer, FP_SEG(env_ptr), FP_OFF(env_ptr), ++count ); env_ptr[count] = '\0'; } #else (void) sprintf(env_ptr,"%s=%s",argv[1],argv[2]); env_ptr[strlen(env_ptr)+1] = '\0'; /* need two nulls to terminate env */ #endif exit(0); }
allbery@ncoast.ORG (Brandon S. Allbery) (01/29/89)
As quoted from <7026@june.cs.washington.edu> by ka@june.cs.washington.edu (Kenneth Almquist): +--------------- | These behave identically. A fair number of years ago, AT&T decided to | switch from the "%02d" format to the "%.2d" format. A couple of reasons | for this may be: | | 1) Conceptual simplicity. The printf format has a precision field | for use by the %s and the floating point formats; it makes sense | to use this same field for integer formats rather than ignoring | the precision and using some other method of getting zero padding. | | 2) Flexibility. Using the precision to specify the zero padding | allows the field width to be used for its normal function even | when zero padding is desired. +--------------- One other reason as well: it's not possible to get zero padding when using variable width fields (%*d) under the old scheme. With the new scheme, use %.*d for zero padding and %*.*d to choose zero padding or none at runtime. ++Brandon -- Brandon S. Allbery, moderator of comp.sources.misc allbery@ncoast.org uunet!hal.cwru.edu!ncoast!allbery ncoast!allbery@hal.cwru.edu Send comp.sources.misc submissions to comp-sources-misc@<backbone> NCoast Public Access UN*X - (216) 781-6201, 300/1200/2400 baud, login: makeuser