Sunday, August 31, 2014

Unix Prog: Formatted I/O(1)

1. Output System definition:

printf outputs content to standard output, fprintf outputs content to specified file stream. sprintf outputs to specified char array, snprintf setup one maximum limits, the string after maximum limit will be truncated.

 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdio.h  
 ......  
 /* Write formatted output to STREAM.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int fprintf (FILE *__restrict __stream,  
           const char *__restrict __format, ...);  
 /* Write formatted output to stdout.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int printf (const char *__restrict __format, ...);  
 /* Write formatted output to S. */  
 extern int sprintf (char *__restrict __s,  
           const char *__restrict __format, ...) __THROWNL;  
 ......  
 /* Maximum chars of output to write in MAXLEN. */  
 extern int snprintf (char *__restrict __s, size_t __maxlen,  
            const char *__restrict __format, ...)  
 ......  

2. Output Example:
fileio.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 int main(int argc, char* argv[])  
 {  
  // printf example  
  // "%+6.3f" means the minimum length of number is 6  
  // decimal part length is at least 3. Use "+" to fill  
  // empty place at the left.  
  float pi = 3.14159;  
  printf("Pi Value: %+6.3f\n", pi);  
   
  // fprintf example  
  FILE *fp;  
  if((fp = fopen("test.txt", "w+")) == NULL) {  
   printf("fopen error!\n");  
   exit(1);  
  }  
   
  fprintf(fp, "Pi Value: %+6.3f\n", pi);  
  fclose(fp);  
   
  // sprintf example  
  char tc[100];  
  sprintf(tc, "Pi Value: %+6.3f", pi);  
  puts(tc);  
   
  // snprintf example  
  snprintf(tc, 9, "Pi Value: %+6.3f\n", pi);  
  puts(tc);  
   
  exit(0);  
 }  

shell:
Run the program, the first line is written by printf, then program write the string to file "test.txt", then use sprintf to write another string(2nd line). The last snprintf defines max length to be 9, so characters after 9th position will be truncated.
 ubuntu@ip-172-31-23-227:~$ ./io.out  
 Pi Value: +3.142  
 Pi Value: +3.142  
 Pi Value  
 ubuntu@ip-172-31-23-227:~$ cat test.txt  
 Pi Value: +3.142  

Note: for sprintf, it is programmer's responsibility to make sure there is enough buffer space to contain the formatted string.

3. Variable Version

Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdio.h  
 ......  
 /* Write formatted output to S from argument list ARG.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,  
            _G_va_list __arg);  
 /* Write formatted output to stdout from argument list ARG.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int vprintf (const char *__restrict __format, _G_va_list __arg);  
 /* Write formatted output to S from argument list ARG. */  
 extern int vsprintf (char *__restrict __s, const char *__restrict __format,  
            _G_va_list __arg) __THROWNL;  
 ......  
 extern int vsnprintf (char *__restrict __s, size_t __maxlen,  
            const char *__restrict __format, _G_va_list __arg)  
    __THROWNL __attribute__ ((__format__ (__printf__, 3, 0)));  
 ......  

Everything is same as above functions, but they are designed for variable arguments.

fileio.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<stdarg.h>  
   
 // vprintf example  
 void myio_1(const char* fm, ...)  
 {  
  va_list args;  
   
  // va_start indicates that args contain all arguments after  
  // parameter fm(not including fm)  
  va_start(args, fm);  
   
  // In this case, args just contain argument "pi"  
  vprintf(fm, args);  
  va_end(args);  
 }  
   
 // vfprintf example  
 void myio_2(const char* fm, ...)  
 {  
  FILE *fp;  
   
  if((fp = fopen("test.txt", "w+")) == NULL) {  
   printf("fopen error!\n");  
   exit(1);  
  }  
   
  va_list args;  
  va_start(args, fm);  
  vfprintf(fp, fm, args);  
  va_end(args);  
   
  fclose(fp);  
 }  
   
 // vsprintf example  
 void myio_3(const char* fm, ...)  
 {  
  va_list args;  
  va_start(args, fm);  
  char tc[100];  
  vsprintf(tc, fm ,args);  
  va_end(args);  
   
  puts(tc);  
 }  
   
 // vsnprintf example  
 void myio_4(const char* fm, ...)  
 {  
  va_list args;  
  va_start(args, fm);  
  char tc[100];  
  vsnprintf(tc, 9, fm, args);  
  va_end(args);  
   
  puts(tc);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  float pi = 3.1415927;  
  myio_1("Pi Value: %+6.3f\n", pi);  
  myio_2("Pi Value: %+6.3f\n", pi);  
  myio_3("Pi Value: %+6.3f", pi);  
  myio_4("Pi Value: %+6.3f", pi);  
  exit(0);  
 }  

shell:
Explanation is same as above, note the last line, which is truncated, because we specify only form at most 9 characters with vsnprintf.
 ubuntu@ip-172-31-23-227:~$ ./io.out  
 Pi Value: +3.142  
 Pi Value: +3.142  
 Pi Value  
 ubuntu@ip-172-31-23-227:~$ cat test.txt  
 Pi Value: +3.142  

No comments:

Post a Comment