首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言實戰練習:統計文件字符數的兩種實現方式

     編輯:關於C語言

C語言文件字符統計實戰演練

統計文件字符數是C語言文件操作的經典入門練習。本文展示兩種不同的輸入方式:命令行參數傳遞文件名,以及運行時交互式輸入文件名,幫助初學者理解main函數參數與標準輸入的區別應用場景。

方案一:命令行參數版本

適用於腳本調用、管道處理、批量處理場景:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    /* 參數校驗:程序名 + 1個文件名 = 2個參數 */
    if (argc != 2) {
        fprintf(stderr, "用法: %s <文件名>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    FILE *fp = fopen(argv[1], "r");  // 只讀模式即可,無需"r+"
    if (!fp) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    long count = 0;
    int ch;  /* 必須用int接收getc返回值,以便判斷EOF(-1) */
    while ((ch = getc(fp)) != EOF) {
        putc(ch, stdout);  // 同步輸出到屏幕,驗證讀取內容
        count++;
    }

    fclose(fp);
    printf("\nFile %s has %ld characters\n", argv[1], count);
    return 0;
}

關鍵點解析

  • argc包含程序名本身,實際參數從argv[1]開始
  • getc/putc是fgetc/fputc的宏版本,性能略優
  • ch聲明為int而非char,因為EOF通常是-1,超出char範圍
  • 使用stderr輸出錯誤信息,便於重定向分離正常輸出與錯誤輸出

方案二:交互式輸入版本

適用於用戶直接運行程序、文件名不固定的場景:

#include <stdio.h>
#include <stdlib.h>

#define MAX_FILENAME 256

int main(void) {
    FILE *fp;
    char filename[MAX_FILENAME];
    long count = 0;
    int ch;

    printf("請輸入文件名: ");
    /* 安全讀取:fgets替代危險的gets */
    if (fgets(filename, sizeof(filename), stdin) == NULL) {
        fprintf(stderr, "讀取輸入失敗\n");
        return EXIT_FAILURE;
    }
    /* 移除fgets保留的換行符 */
    filename[strcspn(filename, "\n")] = '\0';

    fp = fopen(filename, "r");
    if (!fp) {
        perror("fopen");
        return EXIT_FAILURE;
    }

    while ((ch = getc(fp)) != EOF) {
        putc(ch, stdout);
        count++;
    }

    fclose(fp);
    printf("\nFile %s has %ld characters\n", filename, count);
    return 0;
}

安全性改進說明

  1. 棄用gets:原代碼使用gets極其危險,無緩衝區長度檢查,已被C11標準移除。改用fgets指定最大長度
  2. 去除換行符:fgets會保留\n,需手動截斷
  3. 擴大緩衝區:MAX 80過小,現代文件系統路徑常超過260字符,建議256或PATH_MAX
  4. 只讀模式:統計字符無需寫入權限,"r"比"r+"更安全

進階擴展思路

  • 統計行數/單詞數:在循環中增加if (ch == '\n') lines++;邏輯
  • 處理大文件:使用off_t/fseeko支持64位偏移量
  • 多文件批量處理:遍歷argv[1]~argv[argc-1]處理多個文件
  • 字符編碼統計:區分ASCII、UTF-8多字節字符的真實字符數vs字節數

這兩個版本展示了C程序獲取輸入參數的兩種基本模式。實際開發中,命令行參數版本更符合Unix哲學「做一件事並做好」,便於腳本組合;交互版本適合最終用戶直接使用的小工具。根據使用場景選擇合適的交互方式,是編寫優質命令行工具的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved