Saturday, August 30, 2014

Unix Prog: Line-at-a-time I/O

1) gets: read from the standard input stream, add "null" at the end of string. It doesn't store the newline at the end of string

2) fgets: read from the given file stream, add "null" at the end of string, store the newline if there is

3) puts: write the null-terminated string to standard output, null is not written. And it writes one "new-line" after writing the given string

4) fputs: write the null-terminated string to given file stream, null is not written. It doesn't write the "new-line" after writing the given string.

Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/stdio.h  
 ......  
 /* Write a string to STREAM.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int fputs (const char *__restrict __s, FILE *__restrict __stream);  
   
 /* Write a string, followed by a newline, to stdout.  
   
   This function is a possible cancellation point and therefore not  
   marked with __THROW. */  
 extern int puts (const char *__s);  
 ......  
 /* Get a newline-terminated string of finite length from STREAM. 

    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
      __wur;

 #if !defined __USE_ISOC11 \
     || (defined __cplusplus && __cplusplus <= 201103L)
 /* Get a newline-terminated string from stdin, removing the newline.
    DO NOT USE THIS FUNCTION!!  There is no limit on how much it will read.

    The function has been officially removed in ISO C11.  This opportunity
    is used to also remove it from the GNU feature list.  It is now only
    available when explicitly using an old ISO C, Unix, or POSIX standard.
    GCC defines _GNU_SOURCE when building C++ code and the function is still
    in C++11, so it is also available for C++.

    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern char *gets (char *__s) __wur __attribute_deprecated__;
 ......

Note: gets should not be used, since user is allowed to put in string longer than its buffer size, which will overwrite the memory following the buffer.

fileio.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 int main(int argc, char *argv[])  
 {  
  FILE *fp;  
  char buff[BUFSIZ];  
   
  if((fp = fopen("test.txt", "r+")) == NULL) {  
   printf("fopen error!\n");  
   exit(1);  
  }  
   
  // It read the first line, including the newline operator in the end, and  
  // then add the null byte  
  if(fgets(buff, BUFSIZ, fp) != buff) {  
   printf("fgets error!\n");  
   exit(2);  
  }  
   
  // It write the first line, including the newline operator which is already  
  // stored in buff in last step, the null byte is not written  
  if(fputs(buff, stdout) < 0) {  
   printf("fputs error!\n");  
   exit(3);  
  }  
   
  // It read the line from stdin, NOT including the newline operator in the end, and  
  // then add the null byte  
  if(gets(buff) != buff) {  
   printf("gets error!\n");  
   exit(4);  
  }  
   
  // It write the line(not having newline), and then "add" the newline operator by itself  
  // the null byte is not written  
  if(puts(buff) < 0) {  
   printf("puts error!\n");  
   exit(5);  
  }  
   
  fclose(fp);  
  exit(0);  
 }  

shell:
1) Print out the content in test.txt
2) run the program, opening the test.txt, output the first line of test.txt: "Hello world!", then it paused to ask user to input one string, and put it out to standard output.
 ubuntu@ip-172-31-23-227:~$ cat test.txt  
 Hello world!  
 Amazing world!  
 ubuntu@ip-172-31-23-227:~$ ./io.out  
 Hello world!  
 Hello New York  
 Hello New York  

No comments:

Post a Comment