Sunday, August 31, 2014

Unix Prog: Formatted I/O(2)

1. Input System Calls

scanf read formatted input from standard input, fscanf read formatted input from specified file stream, sscanf read formatted input from given string.

Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdio.h  
 ......  
 /* Read formatted input from STREAM.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int fscanf (FILE *__restrict __stream,  
           const char *__restrict __format, ...) __wur;  
 /* Read formatted input from stdin.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int scanf (const char *__restrict __format, ...) __wur;  
 /* Read formatted input from S. */  
 extern int sscanf (const char *__restrict __s,  
           const char *__restrict __format, ...) __THROW;  
 ......  

2. Formatted Input example:

fileio.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<string.h>  
   
 int main(int argc, char* argv[])  
 {  
  // scanf example, provide ti's address to populate  
  // the result from standard input  
  int ti;  
  if(scanf("%d", &ti) < 0) {  
   printf("scanf error!\n");  
   exit(1);  
  }  
   
  printf("%d\n", ti);  
   
  // fscanf example, provide the string address tc  
  // to populate the string from "test.txt"  
  FILE *fp;  
  if((fp = fopen("test.txt", "r+")) == NULL) {  
   printf("fopen error!\n");  
   exit(1);  
  }  
   
  char tc[100];  
  fscanf(fp, "%s", tc);  
   
  printf("%s\n", tc);  
   
  // sscanf example, tc string contains "Hello world!"  
  // provide another string address tc2 to populate the  
  // string from tc  
  char tc2[100];  
  strcpy(tc, "Hello world!");  
  sscanf(tc, "%s", tc2);  
   
  printf("%s\n", tc2);  
  exit(0);  
 }  

shell:
Run the program, it will firstly pause to ask user to input an integer from standard input, we input 100, and then it output the integer. Next step, it read a string from test.txt, it stopped when encountering the space, so the string read in is "Hello", and it output this string to standard output. Lastly, it read string "hello" again from tc char array, and save into tc2 char array, then output the string to standard output.
 ubuntu@ip-172-31-23-227:~$ ./io.out  
 100  
 100  
 Hello  
 Hello  

3. Variadic Arguments Version

definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdio.h  
 ......  
 /* Read formatted input from S into argument list ARG.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,  
           _G_va_list __arg)  
    __attribute__ ((__format__ (__scanf__, 2, 0))) __wur;  
   
 /* Read formatted input from stdin into argument list ARG.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int vscanf (const char *__restrict __format, _G_va_list __arg)  
    __attribute__ ((__format__ (__scanf__, 1, 0))) __wur;  
   
 /* Read formatted input from S into argument list ARG. */  
 extern int vsscanf (const char *__restrict __s,  
           const char *__restrict __format, _G_va_list __arg)  
    __THROW __attribute__ ((__format__ (__scanf__, 2, 0)));  
 ......  

fileio.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<stdarg.h>  
 #include<unistd.h>  
 #include<string.h>  
   
 // vscanf example  
 void my_io1(const char* fm, ...)  
 {  
  va_list args;  
   
  // va_start indicates that args should be arguments after fm  
  va_start(args, fm);  
   
  // vscanf read data from standard input based on the format specified  
  // by fm, and save data into variable whose address is provided by args  
  vscanf(fm, args);  
  va_end(args);  
 }  
   
 // vfscanf example  
 void my_io2(const char* fm, ...)  
 {  
  va_list args;  
  FILE *fp;  
   
  va_start(args, fm);  
  if((fp = fopen("test.txt", "r+")) == NULL) {  
   printf("fopen error!\n");  
   exit(1);  
  }  
   
  // vfscanf read data from specified file stream, based on format  
  // specified by fm, and save data into variable whose address is provided  
  // by args  
  vfscanf(fp, fm, args);  
  va_end(args);  
 }  
   
 // vsscanf example  
 void my_io3(const char* sr, const char* fm, ...)  
 {  
  va_list args;  
  va_start(args, fm);  
   
  // sr contains the data source waiting to be read, fm is the format  
  // specifying the reading type, args contain the variable address  
  vsscanf(sr, fm, args);  
  va_end(args);  
 }  
 int main(int argc, char* argv[])  
 {  
  int ti;  
  my_io1("%d", &ti);  
  printf("after vscanf: %d\n", ti);  
   
  char tc1[100];  
  my_io2("%s", tc1);  
  printf("after vfscanf: %s\n", tc1);  
   
  char tc2[100];  
  strcpy(tc1, "Hello world!");  
  my_io3(tc1, "%s", tc2);  
  printf("after vsscanf: %s\n", tc2);  
   
  exit(0);  
 }  

shell:
1) Print out the content of test.txt
2) Run the program, it firstly ask user to input one integer, we type 999
3) It call vscanf to read integer from standard input, and save to variable whose address is provided by args.
4) It call vfscanf to read string from test.txt, and save to character array provided by args, since fscanf will stop when encountering the space, so only "Hello" is read
5) It call vsscanf to read string from provided character array, and save to character array provided by args, it will also stop when encountering the space, so only "Hello" is read.
 ubuntu@ip-172-31-23-227:~$ cat test.txt  
 Hello world!  
 ubuntu@ip-172-31-23-227:~$ ./io.out  
 999  
 after vscanf: 999  
 after vfscanf: Hello  
 after vsscanf: Hello  

No comments:

Post a Comment