2010-02-24 25 views
5

Chúng tôi có ứng dụng C++/MFC cho phép người dùng tùy chỉnh định dạng ngày thông qua các tệp cấu hình. Không muốn phát minh lại bánh xe, tôi chuyển chuỗi định dạng đến CTime :: Format ("< chuỗi định dạng>") để thực hiện định dạng thực. Trong phần trình bày, Định dạng gọi một biến thể của hàm C tiêu chuẩn strftime().Gọi một cách an toàn với các chuỗi định dạng không đáng tin cậy

Đương nhiên, người dùng có thể vô tình nhập chuỗi định dạng không hợp lệ. (Ví dụ: "% s" thay vì "% S".) Khi điều này xảy ra, C Thời gian chạy gọi số Invalid Argument Handler, theo mặc định, thoát khỏi ứng dụng. (Không có ngoại lệ để bắt - chỉ cần thoát ứng dụng.)

Câu hỏi của tôi là cách xử lý một cách duyên dáng đầu vào không đáng tin cậy này. Về lý thuyết, tôi có thể viết trình phân tích cú pháp/trình duyệt tính hợp lệ của riêng tôi cho chuỗi định dạng, nhưng điều này nghe có vẻ như lãng phí thời gian. Thay vào đó, tốt nhất mà tôi có thể đưa ra là để thiết lập riêng (toàn cầu) handler lập luận hợp lệ của tôi mà, thay vì thoát, ném một Đối số ngoại lệ không hợp lệ:

void MyInvalidParameterHandler(
    const wchar_t* expression, 
    const wchar_t* function, 
    const wchar_t* file, 
    unsigned int line, 
    uintptr_t pReserved) 
{ 
    ::AfxThrowInvalidArgException(); 
} 

này dường như để làm việc, và cho phép tôi để rõ ràng nắm bắt (và xử lý một cách duyên dáng) các ngoại lệ đối số không hợp lệ trong các trường hợp mà tôi "mong đợi" chúng xảy ra. Tuy nhiên, tôi lo ngại rằng tôi đang ghi đè cài đặt toàn cầu, thời gian chạy trong một ứng dụng lớn để giải quyết vấn đề "cục bộ" tương đối-- Tôi sẽ ghét việc sửa lỗi này gây ra các sự cố khác ở nơi khác.

Cách tiếp cận này có hợp lý không? Hoặc là có một cách tiếp cận sạch hơn giải quyết vấn đề này?

Trả lời

3

Nếu bạn chỉ quan tâm đến việc gặp lỗi này vào những thời điểm nhất định, bạn có thể tạm thời thay thế trình xử lý thông số không hợp lệ và sau đó đặt lại sau khi bạn đã định dạng.

_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(MyInvalidParameterHandler); 

// Your try/Format/catch code here 

_set_invalid_parameter_handler(oldHandler); 

Tất nhiên, tôi cho rằng nếu bạn có nhiều chuỗi trong chương trình, một chuỗi khác có thể sẽ gọi trình xử lý thông số không hợp lệ của bạn trong khi nó được đặt. Bạn sẽ phải xác định khả năng đó là bao nhiêu.

Ngoài việc viết chức năng xác nhận của chính bạn, tôi không chắc bạn có thể làm điều này bằng cách nào khác.

+0

Cảm ơn bạn đã đề xuất. Thật không may, ứng dụng của tôi thực sự là đa luồng, vì vậy tôi không nghĩ rằng tôi có thể chuyển đổi một cách an toàn trình xử lý qua lại. (Trình xử lý tham số không hợp lệ là toàn cục, chứ không phải chỉ dành riêng cho từng chủ đề.) –

+0

Trong trường hợp đó, tôi tin rằng bạn sẽ cần tạo hàm xác nhận của riêng mình. Nó không phải là khó khăn. Nếu bạn nhìn vào strftime.c trong mã nguồn CRT, bạn sẽ thấy một hàm có tên _expandtime. Nó chứa một tuyên bố trường hợp cho tất cả các định dạng được hỗ trợ định dạng. Bạn có thể sử dụng nó làm cơ sở cho chức năng của bạn. – Dustin

+0

Một khả năng là thêm trình xử lý thông số không hợp lệ của riêng bạn mà không làm gì cả. Các tài liệu nói rằng nếu điều khiển trả về hàm gọi, nó sẽ trả về một mã lỗi. – Dustin

Các vấn đề liên quan