2013-04-11 20 views
7

Trong C++, chúng tôi có một phương pháp để tìm kiếm văn bản trong một tệp. Nó hoạt động bằng cách đọc tệp đến một biến và sử dụng strstr. Nhưng chúng tôi gặp rắc rối khi tập tin trở nên rất lớn.Lỗi với find.exe?

Tôi nghĩ tôi có thể giải quyết vấn đề này bằng cách gọi find.exe bằng _popen. Nó hoạt động tìm kiếm, trừ khi những điều kiện này đều đúng:

  • Các tập tin được loại unicode (BOM = FFFE)
  • Các tập tin là CHÍNH XÁC 4096 byte
  • Các văn bản mà bạn đang tìm kiếm là cuối cùng văn bản trong tập tin

Để tái tạo, bạn có thể làm điều này:

  1. mở notepad
  2. Insert 2046 X thì A vào cuối
  3. Save as test.txt, encoding = "unicode"
  4. Xác nhận tập tin đó là chính xác 4096 byte
  5. Mở một dấu nhắc lệnh và gõ: find "A"/c test2.txt -> không chạm

tôi cũng đã cố gắng này:

  • Thêm hoặc xóa một X, và bạn sẽ nhận được một hit (tập tin không phải là 4096 bytes nữa)
  • Lưu dưới dạng UTF-8 (và thêm đủ X để tệp lại là 4096 byte), và bạn nhận được một hit
  • Tìm kiếm thứ gì đó ở giữa tệp (tệp vẫn unicode và 4096 byte) và bạn nhận được cú đánh.

Đây có phải là lỗi hoặc có điều gì đó tôi bị thiếu không?

+2

Điều này thật thú vị. Bạn đã thử nó với bội số khác của 1024? Hay 4096? I E. 8192 byte? –

+0

1024 và 2048 là ok, nhưng nó không thành công trên 8192. –

+0

Wow - đó là một lỗi khó chịu: (Nó cũng thất bại nếu kích thước tập tin là 8192 byte dài. Khi bạn tìm kiếm một ký tự ở giữa, nó tìm thấy " dòng ", nhưng thông báo rằng nhân vật cuối cùng là mất tích từ đầu ra! Bạn nhận được X'es nhưng không A của – dbenham

Trả lời

4

Lỗi rất thú vị.

Câu hỏi này khiến tôi thực hiện một số thử nghiệm trên XP và Win 7 - các hành vi khác nhau.

XP

ANSI - TÌM không thể đọc qua 1023 ký tự (1023 byte) trên một dòng đơn. FIND có thể khớp với một dòng vượt quá 1023 ký tự miễn là chuỗi tìm kiếm khớp với trước 1024. Bản in dòng khớp được cắt ngắn sau 1023 ký tự.

Unicode - TÌM không thể đọc quá 1024 ký tự (2048 byte) trên một dòng. FIND có thể khớp với một dòng vượt quá 1024 ký tự miễn là chuỗi tìm kiếm khớp với trước 1025. Bản in dòng khớp được cắt ngắn sau 1024 ký tự.

Tôi thấy rất kỳ quặc rằng giới hạn dòng cho Unicode và ANSI trên XP không phải là số byte giống nhau, cũng không phải là một bội số đơn giản. Giới hạn Unicode được biểu thị bằng byte gấp 2 lần giới hạn cho ANSI cộng 1.

Lưu ý: cắt ngắn các đường thẳng dài cũng cắt ngắn ký tự dòng mới, vì vậy dòng khớp tiếp theo sẽ xuất hiện được nối thêm vào dòng trước đó.Bạn có thể nói đó là một dòng mới nếu bạn sử dụng tùy chọn/N.

Window 7

ANSI - Tôi đã không tìm thấy một giới hạn chiều dài dòng tối đa có thể được tìm kiếm, (mặc dù tôi đã không cố gắng rất cứng). Bất kỳ dòng khớp nào vượt quá 4095 ký tự (4095 byte) sẽ bị cắt bớt sau 4095 ký tự. FIND có thể tìm kiếm thành công 4095 ký tự trên một dòng, nó không thể hiển thị tất cả chúng.

Unicode - Tôi không tìm thấy giới hạn cho độ dài dòng tối đa có thể tìm kiếm được (mặc dù tôi không cố gắng hết sức). Bất kỳ dòng khớp nào vượt quá 2047 ký tự (4094 byte) sẽ bị cắt bớt sau 2047 ký tự. FIND có thể tìm kiếm thành công 2047 ký tự trên một dòng, nó chỉ không thể hiển thị tất cả chúng.

Vì độ dài byte Unicode luôn là bội số của 2 và độ dài hiển thị ANSI tối đa là số lẻ, nên có nghĩa là độ dài dòng hiển thị tối đa bằng byte ít Unicode hơn ANSI.

Nhưng sau đó cũng có lỗi Unicode lạ. Nếu độ dài tệp Unicode là bội số chính xác của 4096 byte, thì ký tự cuối cùng không thể được tìm kiếm hoặc in. Nó không quan trọng nếu tập tin có chứa một dòng hoặc nhiều dòng. Nó chỉ phụ thuộc vào tổng chiều dài tập tin.

Tôi thấy điều thú vị là bội số của lỗi 4096 nằm trong một trong độ dài dòng in tối đa (tính theo byte). Nhưng tôi không biết liệu có mối quan hệ nào giữa những hành vi đó hay chỉ đơn giản là trùng hợp ngẫu nhiên.

Lưu ý: cắt ngắn các đường kẻ dài phù hợp cũng cắt bớt bất kỳ ký tự dòng mới nào, do đó, dòng phù hợp tiếp theo sẽ xuất hiện để được nối thêm vào dòng trước đó. Bạn có thể nói đó là một dòng mới nếu bạn sử dụng tùy chọn/N.

+0

Lỗi rất thú vị! – Patashu