Catalog
1.2 freopen standard output to file
1. Use of temporary documents
1.1 Reorientation using shell
The first idea is to redirect the command output to a temporary file, read the temporary file in our application program, and get the results of the execution of external commands. The code is as follows:
#define CMD_STR_LEN 1024 int mysystem(char* cmdstring, char* tmpfile) { char cmd_string[CMD_STR_LEN]; tmpnam(tmpfile); sprintf(cmd_string, "%s > %s", cmdstring, tmpfile); return system(cmd_string); }
1.2 freopen standard output to file
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> int main() { if(freopen("file.txt","w",stdout)==NULL) fprintf(stderr,"error\n"); system("ls -ahl"); printf("This is in the file\n"); //This sentence will be displayed in file.txt. fclose(stdout); return 0; }
freopen can also redirect standard input.
//First, create an in.txt text document and write a number of numbers in the same path #include <stdio.h> #include <stdlib.h> int main() { freopen("in.txt","r",stdin); //Read data from in.txt freopen("out.txt","w",stdout); // Write the final data into out.txt int a,b; while(scanf("%d%d",&a,&b)!=EOF) //Data is entered from in.txt printf("%d\n",a+b); //Write to out.txt fclose(stdin); fclose(stdout); return 0; }
This use of temporary files as a bridge between the application and external commands, in the application program need to read the file, and then delete the temporary file, more cumbersome, the advantage is simple to achieve, easy to understand. Is there a way to do this without resorting to temporary documents?
2. Use anonymous pipes
In the book Advanced Programming for UNIX Environment, we give an example of output of program results to paging programs through anonymous pipelines, so we can also connect the results of external commands to applications through pipelines. The method is to fork a child process and create an anonymous pipeline, execute shell command in the child process, and dup its standard output to the input of anonymous pipeline. The parent process reads from the pipeline, and then obtains the output of shell command. The code is as follows:
/** * Enhanced system function that returns the output of the system call * * @param[in] cmdstring A command string that calls an external program or script * @param[out] buf Buffer that returns the result of an external command * @param[in] len Buffer Buffer Length * * @return 0: Success; - 1: Failure */ int mysystem(char* cmdstring, char* buf, int len) { int fd[2]; pid_t pid; int n, count; memset(buf, 0, len); if (pipe(fd) < 0) return -1; if ((pid = fork()) < 0) return -1; else if (pid > 0) /* parent process */ { close(fd[1]); /* close write end */ count = 0; while ((n = read(fd[0], buf + count, len)) > 0 && count > len) count += n; close(fd[0]); if (waitpid(pid, NULL, 0) > 0) return -1; } else /* child process */ { close(fd[0]); /* close read end */ if (fd[1] != STDOUT_FILENO) { if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) { return -1; } close(fd[1]); } if (execl("/bin/sh", "sh", "-c", cmdstring, (char*)0) == -1) return -1; } return 0; }
3. Use popen
In the process of learning unix programming, it is found that the system also provides a popen function, which can process and call the shell very simply. Its function prototype is as follows:
#include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream);
The purpose of this function is to create a pipeline, fork a process, and then execute the shell. The output of the shell can be obtained by reading the file. This method avoids the creation of temporary files and is not limited by the number of characters output. It is recommended to use this method.
popen determines the direction of input / output of command by type r or w, which is relative to the pipeline of command. r denotes that command reads from the pipeline, w denotes that command outputs to its stdout through the pipeline, and popen returns the file flow pointer of the FIFO pipeline. pclose is used to close the pointer after use.
Let's look at an example:
/******************************************************************************************* ** Name:popen.c ** This program is used to show the usage of popen() . ** Author:zieckey,(zieckey@yahoo.com.cn) ** Date:2007/9/30 11:47 ** All rights reserved! *******************************************************************************************/ #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main( void ) { FILE *stream; FILE *wstream; char buf[1024]; memset( buf, '\0', sizeof(buf) );//Initialize buf to avoid scrambling to files later stream = popen( "ls -l", "r" ); //The output of the "ls-l" command is read through the pipeline (the "r" parameter) to FILE* stream wstream = fopen( "test_popen.txt", "w+"); //Create a new writable file fread( buf, sizeof(char), sizeof(buf), stream); //Read the data stream just from FILE* stream into buf fwrite( buf, 1, sizeof(buf), wstream );//Writing data in buf to the stream corresponding to FILE * wstream is also written to a file pclose( stream ); fclose( wstream ); return 0; }
Read data directly from the data stream returned by popen using the getline function:
#define _GNU_SOURCE #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> int main (void) { FILE *stream; char *line = NULL; size_t len = 0; ssize_t read; stream = popen ("ls -l", "r"); while ((read = getline (&line, &len, stream)) != -1) { printf ("Retrieved line of length %zu :\n", read); printf ("%s", line); } pclose (stream); return 0; }
4. Summary
Statistical data show that the defect rate of code is certain, independent of the language used. Linux Provide a lot of utilities and scripts, call tools and scripts in the program, can undoubtedly simplify the program, thereby reducing the number of code defects. linux shell script is also a powerful tool. We can write scripts as needed and then call custom scripts in programs.
For example: indent getline.c can sort out style issues such as code indentation.
sed-i's/xc2xa0/x 20/g'test.c replaces Chinese in test.c with spaces
Sed-i's/xc2xa0//g'getline.c Deletes Chinese from test.c