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

VC++ 讀取文字檔資料完整教學:CStdioFile + sscanf 高效解析

     編輯:VC 教學

為什麼選擇文字檔儲存資料?

  • 無需註冊資料源 (ODBC/ADO),部署簡單
  • 人類可讀,便於除錯與手工編輯
  • 跨平台相容性佳
  • 程式碼輕量,無資料庫引擎開銷

核心策略:逐行讀取 + 格式化解析

  1. 使用 CStdioFile::ReadString 逐行讀入 CString 緩衝區
  2. 使用 sscanf 依格式字串解析欄位,自動忽略任意數量空白
  3. 將解析結果轉型為所需型別 (int, float, double 等)

關鍵優勢:sscanf 對格式極度寬容——欄位間可有任意空白、Tab、行首行尾空白皆可正確解析。

MFC 單一檔案專案完整實作

專案建立

VC6.0 → MFC AppWizard (exe) → Single Document → 專案名 ReadCoordinate。

View 類別新增成員

// ReadCoordinateView.h
class CReadCoordinateView : public CView {
    // ...
public:
    CArray<CPoint, CPoint> m_PointArray; // 座標點陣列
    int m_PointNum;                      // 點數
    // 建構子初始化 m_PointNum = 0
};

選單命令處理

// ReadCoordinateView.cpp
void CReadCoordinateView::OnReadData() {
    CFileDialog dlg(TRUE, _T("txt"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                    _T("文字檔 (*.txt)|*.txt|所有檔案 (*.*)|*.*||"));
    if (dlg.DoModal() != IDOK) return;

    CStdioFile file;
    if (!file.Open(dlg.GetPathName(), CFile::modeRead | CFile::typeText)) {
        AfxMessageBox(_T("無法開啟檔案"));
        return;
    }

    CString line;
    char temp1[32], temp2[32];

    // 讀第一行:點數
    if (!file.ReadString(line)) return;
    memset(temp1, 0, sizeof(temp1));
    sscanf(line, "%s", temp1);
    m_PointNum = atoi(temp1);
    m_PointArray.RemoveAll();

    // 逐行讀取座標
    for (int i = 0; i < m_PointNum && file.ReadString(line); ++i) {
        memset(temp1, 0, sizeof(temp1));
        memset(temp2, 0, sizeof(temp2));
        if (sscanf(line, "%s %s", temp1, temp2) == 2) {
            int x = atoi(temp1);
            int y = atoi(temp2);
            m_PointArray.Add(CPoint(x, y));
        }
    }
    file.Close();

    // 繪圖顯示
    CDC* pDC = GetDC();
    for (int i = 0; i < m_PointNum - 1; ++i) {
        pDC->MoveTo(m_PointArray[i]);
        pDC->LineTo(m_PointArray[i + 1]);
    }
    ReleaseDC(pDC);
}

測試資料檔範例 (coords.txt)

5
10 20
30 40
45 85
100 120
200 300

以下格式同樣可正確解析:

5
    10      20
30    40
45                    85
100 120
200     300

擴充應用:支援浮點數、多欄位、CSV 格式

// 浮點數座標
double x, y;
sscanf(line, "%lf %lf", &x, &y);

// 多欄位:ID, X, Y, Z, Label
int id; double x, y, z; char label[64];
sscanf(line, "%d %lf %lf %lf %s", &id, &x, &y, &z, label);

// CSV 逗號分隔
sscanf(line, "%d,%lf,%lf,%lf,%[^,]", &id, &x, &y, &z, label);

效能與健壯性建議

場景建議做法
超大檔案 (>100MB)改用 CFile + 手動緩衝區,避免 CString 記憶體壓力
編碼非 ANSI讀入後用 MultiByteToWideChar 轉 Unicode,或直接用 CStdioFile Unicode 版本 (VS2005+)
異常行處理檢查 sscanf 回傳值 (成功轉換欄位數),記錄錯誤行號並跳過
高頻讀寫考慮記憶體對應檔案 CreateFileMapping

總結

CStdioFile + sscanf 是 VC++ 讀取結構化文字檔的黃金組合:程式碼極簡、格式寬容、效能足夠、無外部依賴。掌握此法,輕鬆應對地質座標、感測器日誌、CSV 匯入等實務需求。

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