2012-03-13 24 views
6

Tôi đang sử dụng std::copy để sao chép các đối tượng trong std::deque vào một tệp. Mã đang làm việc tốt nhưng tôi cần phải kiểm tra xem sao chép đã thành công và theo đó tôi cần phải thiết lập cờ hoặc người nào khác ném ngoại lệ.Cách trả về giá trị của std :: sao chép trong trường hợp thành công hay thất bại?

Tôi đã googled nhưng không thể tìm thấy giải pháp cách kiểm tra xem std::copy đã sao chép thành công các giá trị vào tệp hay chưa.

Ai đó có thể vui lòng ném đèn lên đó.

+3

Bạn không thể kiểm tra [trạng thái I/O luồng] (http://en.cppreference.com/w/cpp/io/ios_base/iostate)? –

Trả lời

5

Nếu ghi vào tệp không thành công, thì cờ báo lỗi của luồng tệp sẽ được đặt - bạn có thể kiểm tra sau khi sao chép hoặc gọi hàm thành viên exceptions trước để làm cho nó ném một ngoại lệ do lỗi. Nếu bất cứ điều gì khác thất bại, sau đó một ngoại lệ sẽ được ném.

2

AFAIK std :: thuật toán sao chép không kiểm tra bất kỳ thứ gì và chỉ lặp qua tất cả các phần tử và sao chép chúng vào trình lặp đầu ra. Điều này có nghĩa là bạn nên cung cấp đủ không gian trong bản lặp đầu ra nếu không hành vi không được chỉ định.

Vì vậy, trong trường hợp của bạn, bạn nên tự kiểm tra xem tệp đầu ra có ghi được không, vv .. Một trong những cách có thể để kiểm tra điều này, tôi nghĩ sử dụng cờ lỗi cho luồng tệp bạn đang sử dụng, tức là sau khi sao chép ofstreamgood (bạn có thể sử dụng good(), eof(), fail()bad() chức năng cho việc này).

Cách tiếp cận thứ hai là kiểm tra giá trị trả lại của std::copy. Khi nó trả về một iterator đến cuối dãy đích (trỏ đến phần tử sau bản sao cuối cùng) thì bạn có thể tính toán sự khác biệt giữa giá trị trả về của std::copy và trình lặp đầu ra của bạn và đảm bảo rằng nó bằng với kích thước của deque của bạn. Ví dụ. (Giả)

OutputIterator result = std::copy(input.begin(), input.end(), output); 
assert(result - output == input.end() - input.begin()); 

EDIT: Cách tiếp cận thứ hai chỉ hoạt động khi output cũng là input type iterator, vì vậy std::distance để làm việc cho nó. Sẽ chính xác hơn khi viết:

assert(std::distance(output, result) == std::distance(input.begin(), input.end())); 
+0

Tất nhiên bạn không thể thực hiện tiếp cận thứ hai với 'std :: ostream_iterator', vì nó là một trình lặp đầu ra,' std :: distance' sẽ không hoạt động. –

+0

Có bạn đã đúng. Cách tiếp cận thứ hai sẽ chỉ hoạt động khi 'output' cũng là bộ lặp đầu vào. –

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