《C程序設計語言》------關於輸入輸出(stdin、stdout、stderr)


啟動一個C語言程序時,操作系統環境負責打開三個文件,並將這3個文件的指針提供給該程序。這3個文件分別為標准輸入(stdin)、標准輸出(stdout)、標准錯誤(stderr)。它們在<stdio.h>中聲明,大多數環境中,stdin指向鍵盤,stdout、stderr指向顯示器。之所以使用stderr,若因某種原因造成其中一個文件無法訪問,相應的診斷信息要在該鏈接的輸出的末尾才能打印出來。當輸出到屏幕時,這種處理方法尚可接受,但如果輸出到一個文件或通過管道輸出到另一個程序時,就無法接受了。若有stderr存在,即使對標准輸出進行了重定向,寫到stderr中的輸出通常也會顯示在屏幕上。

exit():在主程序main中,語句return expr等價於exit(expr)。但是,函數exit有一個優點,它可以從其他函數中調用,並且可以用查找程序查找這些調用。exit(0)為正常退出,exit(1)只要里面的參數不為零,為非正常退出,。

fgets:

char *fgets(char *line, int maxline, FILE *fp);

 fp指向的文件中讀取下一個輸入行(包括換行符),並將它存放在字符數組line中,最多讀取maxline-1個字符。讀取的行將以'\0'結尾,結尾保存到數組中。通常,fgets返回line,遇到文件結尾或發生錯誤,返回NULL。

 

晚上做了一個題,用去了很長時間,就因為一些簡單錯誤,在此記錄。《C程序設計語言》第2版(中文)P145 7-6:

編寫一個程序,比較兩個文件並打印它們第一個不相同的行。

 1 #include <stdio.h>
2
3 #define MAXSIZE 100
4
5 main(int argc, char *argv[])
6 {
7 FILE *fp1, *fp2;
8 void filecmp(FILE *, FILE *);
9 char *prog = argv[0];
10
11 if (argc < 3) {
12 fprintf(stderr, "error: no enough files!\n");
13 exit(1);
14 }
15 else {
16 if ((fp1 = fopen(*++argv, "r")) == NULL) {
17 fprintf(stderr, "%s: can't open %s\n", prog, *argv);
18 exit(2);
19 }
20 else if ((fp2 = fopen(*++argv, "r")) == NULL) {
21 fprintf(stderr, "%s: can't open %s\n", prog, *argv);
22 exit(3);
23 }
24 else {
25 filecmp(fp1, fp2);
26 fclose(fp1);
27 fclose(fp2);
28 }
29 }
30 exit(0);
31 }
32
33 void filecmp(FILE *ifp1, FILE *ifp2)
34 {
35 char line1[MAXSIZE], line2[MAXSIZE];
36
37 int count = 0;
38 int full = 0;
39
40 while ((fgets(line1, MAXSIZE, ifp1) != NULL) &&
41 (fgets(line2, MAXSIZE, ifp2) != NULL)) {
42 if ((strcmp(line1, line2)) == 0) {
43 count++;
44 full = 1;
45 }
46 else {
47 fprintf(stdout, "The number of different line is %d\n", count);
48 fprintf(stdout, "%s\n", line1);
49 fprintf(stdout, "%s\n", line2);
50 return;
51 }
52 }
53 if (!full)
54 fprintf(stderr, "error: cannont read!\n");
55 else
56 fprintf(stderr, "same files!\n");
57 }

錯誤1:將第35行寫為:

char *line1, *line2;

這里明顯混淆了數組與指針的關系,若為當做數組,實際是第一個數的地址,而不是整個數組。

錯誤2:第42行后,加了兩句:

fp1++;
fp2++;

fp1、fp2實際是指向文件的文件描述符,不能做加減運算。按照我的本意是fp1自加后指向文件的下一行,實際上fgets函數讀取下一行時已經加上換行符了。

fgets函數如下:

 1 char *fgets(char *s, int n, FILE *fp)
2 {
3 register int c;
4 register char *cs;
5
6 while (--n > 0 && (c = getc(iop)) != EOF)
7 if ((*cs++ = c) == '\n')
8 break;
9 *cs = '\0';
10 return (c == EOF && cs == s) ? NUll : s;
11 }

第7行寫的很清楚,讀了換行符。

總結經驗:要先弄清函數各個參數的用法再動手,否則事倍功半。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM