[ Pobierz całość w formacie PDF ]
.void main(){int x;int y;scanf("%d%d",&x,&y);}But in this example scanf() has been told to store the data at the addresses suggested by the current values of `x' and `y'! An easy and common mistake to make, and yet one that can have very peculiar effects.void main(){int x;int y;scanf("%d%d",x,y);}The answer is, don't use scanf(), use fgets() and parse your string manually using the standard library functions strtod(), strtol() and strtoul().Here is the basis of a simple input string parser that returns the individual input fields from an entered string;#include <stdio.h>#include <string.h>void main(){char input[80];char *p;puts("\nEnter a string ");fgets(input,79,stdin);/* now parse string for input fields */puts("The fields entered are:");p = strtok(input,", ");while(p){puts(p);p = strtok(NULL,", ");}}SIZEOFA preprocessor instruction, `sizeof', returns the size of an item, be it a structure, pointer, string or whatever.However! take care when using `sizeof'.Consider the following program;#include <stdio.h>#include <mem.h>char string1[80]; char *text = "This is a string of data" ;void main(){/* Initialise string1 correctly */memset(string1,0,sizeof(string1));/* Copy some text into string1 ? */memcpy(string1,text,sizeof(text));/* Display string1 */printf("\nString 1 = %s\n",string1);}What it is meant to do is initialise all 80 elements of string1 to zeroes, which it does alright, and then copy the constant string `text' into the variable `string1'.However, variable text is a pointer, and so the sizeof(text) instruction returns the size of the character pointer (perhaps two bytes) rather than the length of the string pointed to by the pointer! If the length of the string pointed to by `text' happened to be the same as the size of a character pointer then no error would be noticed.INTERRUPTSThe IBM PC BIOS and DOS contain functions that may be called by a program by way of the function's interrupt number.The address of the function assigned to each interrupt is recorded in a table in RAM called the interrupt vector table.By changing the address of an interrupt vector a program can effectively disable the original interrupt function and divert any calls to it to its own function.This was done by the critical error handler described in the section on error handling.Borland's Turbo C provides two library functions for reading and changing an interrupt vector.These are: setvect() and getvect().The corresponding Microsoft C library functions are: _dos_getvect() and _dos_setvect().getvect() has the function prototype;void interrupt(*getvect(int interrupt_no))();setvect() has the prototype;void setvect(int interrupt_no, void interrupt(*func)());To read and save the address of an existing interrupt a program uses getvect() thus;/* Declare variable to record old interrupt */void interrupt(*old)(void);main(){/* get old interrupt vector */old = getvect(0x1C);.}Where 0x1C is the interrupt vector to be retrieved.To then set the interrupt vector to a new address, our own function, we use setvect() thus;void interrupt new(void){./* New interrupt function */.}main(){.setvect(0x1C,new);.}There are two important points to note about interrupts;First, if the interrupt is called by external events then before changing the vector you MUST disable the interrupt callers using disable() and then re-enable the interrupts after the vector has been changed using enable().If a call is made to the interrupt while the vector is being changed ANYTHING could happen!Secondly, before your program terminates and returns to DOS you must reset any changed interrupt vectors! The exception to this is the critical error handler interrupt vector that is restored automatically by DOS, so your program needn't bother restoring it.This example program hooks the PC clock timer interrupt to provide a background clock process while the rest of the program continues to run.If included with your own program that requires a constantly displayed clock on screen, you need only amend the display coordinates in the call to puttext().Sincle the closk display code is called by a hardware issued interrupt, your program can start the clock and forget it until it terminates./* Compile in LARGE memory model */#include <stdio.h>#include <dos.h>#include <time.h>#include <conio.h>#include <stdlib.h>enum { FALSE, TRUE };#define COLOUR (BLUE << 4) | YELLOW#define BIOS_TIMER 0x1Cstatic unsigned installed = FALSE;static void interrupt (*old_tick) (void);static void interrupt tick (void){int i;struct tm *now;time_t this_time;char time_buf[9];static time_t last_time = 0L;static char video_buf[20] ={' ', COLOUR, '0', COLOUR, '0', COLOUR, ':', COLOUR, '0', COLOUR,'0', COLOUR, ':', COLOUR, '0', COLOUR, '0', COLOUR, ' ', COLOUR};enable ();if (time (&this_time) != last_time){last_time = this_time;now = localtime(&this_time);sprintf(time_buf, "%02d:%02d [ Pobierz całość w formacie PDF ]
zanotowane.pl doc.pisz.pl pdf.pisz.pl matkasanepid.xlx.pl
.void main(){int x;int y;scanf("%d%d",&x,&y);}But in this example scanf() has been told to store the data at the addresses suggested by the current values of `x' and `y'! An easy and common mistake to make, and yet one that can have very peculiar effects.void main(){int x;int y;scanf("%d%d",x,y);}The answer is, don't use scanf(), use fgets() and parse your string manually using the standard library functions strtod(), strtol() and strtoul().Here is the basis of a simple input string parser that returns the individual input fields from an entered string;#include <stdio.h>#include <string.h>void main(){char input[80];char *p;puts("\nEnter a string ");fgets(input,79,stdin);/* now parse string for input fields */puts("The fields entered are:");p = strtok(input,", ");while(p){puts(p);p = strtok(NULL,", ");}}SIZEOFA preprocessor instruction, `sizeof', returns the size of an item, be it a structure, pointer, string or whatever.However! take care when using `sizeof'.Consider the following program;#include <stdio.h>#include <mem.h>char string1[80]; char *text = "This is a string of data" ;void main(){/* Initialise string1 correctly */memset(string1,0,sizeof(string1));/* Copy some text into string1 ? */memcpy(string1,text,sizeof(text));/* Display string1 */printf("\nString 1 = %s\n",string1);}What it is meant to do is initialise all 80 elements of string1 to zeroes, which it does alright, and then copy the constant string `text' into the variable `string1'.However, variable text is a pointer, and so the sizeof(text) instruction returns the size of the character pointer (perhaps two bytes) rather than the length of the string pointed to by the pointer! If the length of the string pointed to by `text' happened to be the same as the size of a character pointer then no error would be noticed.INTERRUPTSThe IBM PC BIOS and DOS contain functions that may be called by a program by way of the function's interrupt number.The address of the function assigned to each interrupt is recorded in a table in RAM called the interrupt vector table.By changing the address of an interrupt vector a program can effectively disable the original interrupt function and divert any calls to it to its own function.This was done by the critical error handler described in the section on error handling.Borland's Turbo C provides two library functions for reading and changing an interrupt vector.These are: setvect() and getvect().The corresponding Microsoft C library functions are: _dos_getvect() and _dos_setvect().getvect() has the function prototype;void interrupt(*getvect(int interrupt_no))();setvect() has the prototype;void setvect(int interrupt_no, void interrupt(*func)());To read and save the address of an existing interrupt a program uses getvect() thus;/* Declare variable to record old interrupt */void interrupt(*old)(void);main(){/* get old interrupt vector */old = getvect(0x1C);.}Where 0x1C is the interrupt vector to be retrieved.To then set the interrupt vector to a new address, our own function, we use setvect() thus;void interrupt new(void){./* New interrupt function */.}main(){.setvect(0x1C,new);.}There are two important points to note about interrupts;First, if the interrupt is called by external events then before changing the vector you MUST disable the interrupt callers using disable() and then re-enable the interrupts after the vector has been changed using enable().If a call is made to the interrupt while the vector is being changed ANYTHING could happen!Secondly, before your program terminates and returns to DOS you must reset any changed interrupt vectors! The exception to this is the critical error handler interrupt vector that is restored automatically by DOS, so your program needn't bother restoring it.This example program hooks the PC clock timer interrupt to provide a background clock process while the rest of the program continues to run.If included with your own program that requires a constantly displayed clock on screen, you need only amend the display coordinates in the call to puttext().Sincle the closk display code is called by a hardware issued interrupt, your program can start the clock and forget it until it terminates./* Compile in LARGE memory model */#include <stdio.h>#include <dos.h>#include <time.h>#include <conio.h>#include <stdlib.h>enum { FALSE, TRUE };#define COLOUR (BLUE << 4) | YELLOW#define BIOS_TIMER 0x1Cstatic unsigned installed = FALSE;static void interrupt (*old_tick) (void);static void interrupt tick (void){int i;struct tm *now;time_t this_time;char time_buf[9];static time_t last_time = 0L;static char video_buf[20] ={' ', COLOUR, '0', COLOUR, '0', COLOUR, ':', COLOUR, '0', COLOUR,'0', COLOUR, ':', COLOUR, '0', COLOUR, '0', COLOUR, ' ', COLOUR};enable ();if (time (&this_time) != last_time){last_time = this_time;now = localtime(&this_time);sprintf(time_buf, "%02d:%02d [ Pobierz całość w formacie PDF ]