2009-10-30 27 views
8

Tôi đang viết một chương trình trên nền tảng Linux đang tạo ra các tệp văn bản sẽ được xem trên, chắc chắn, một nền tảng Windows.Thay đổi std :: endl để đưa ra CR + LF thay vì LF

Hiện tại, hãy chuyển std::endl thành một ostream chỉ tạo ký tự CR cho dòng mới. Đương nhiên, các tập tin văn bản trông sai trong MS Notepad.

  1. Có cách nào thay đổi std::endl sao cho nó sử dụng CR + LF cho dòng mới thay vì LF?
  2. Tôi biết tôi có thể viết trình xử lý tùy chỉnh của riêng mình, như win_endl, để tạo dòng mới của riêng mình, nhưng tôi sử dụng biểu tượng std::endl ở nhiều nơi và giống như nhiều lập trình viên, có xu hướng làm điều làm việc có thể. Tôi có thể chỉ đơn giản là quá tải std::endl để sản xuất CR + LF, hoặc là một ý tưởng câm để bảo trì?

NB: Tôi đã kiểm tra this question, nhưng yêu cầu về cách khác và câu trả lời được chấp nhận có vẻ chưa hoàn chỉnh.

+3

Một tùy chọn khác là sử dụng công cụ trên Windows biết cách xử lý các dòng mới của Unix (ví dụ, hầu hết mọi trình soạn thảo khác Notepad) hoặc sử dụng công cụ chuyển đổi kết thúc dòng (thường được gọi là unix2dos.exe hoặc một cái gì đó) . –

+0

@Michael Burr - ý tưởng hay, nhưng khó để hỗ trợ với cơ sở khách hàng của chúng tôi là phản ứng ruột của tôi. –

+1

Nó không phải chạy trên máy khách hàng - có các bộ lọc sẽ thực hiện tương tự trên một hộp Unix. Bạn có thể có các tập tin đầu ra được sản xuất bởi chương trình hiện tại của bạn chạy qua bộ lọc trước khi bạn gói chúng để phân phối cho khách hàng. Nó có vẻ hacky, nhưng tôi nghĩ rằng nó thực sự có thể ít hacky hơn so với mucking xung quanh với C++ streamio (và nó có thể là công việc ít hơn nhiều). –

Trả lời

8

Mở tệp ở chế độ văn bản sẽ khiến cho std::endl được chuyển đổi sang dòng thích hợp kết thúc cho nền tảng của bạn. Vấn đề của bạn là newline thích hợp cho nền tảng của bạn, nhưng các tệp bạn tạo không dành cho nền tảng của bạn.

Tôi không chắc chắn cách bạn lên kế hoạch quá tải hoặc thay đổi endl và thay đổi hành vi của nó chắc chắn sẽ gây bất ngờ cho bất kỳ nhà phát triển nào mới đối với dự án của bạn. Tôi khuyên bạn nên chuyển sang win_endl (nên là một tìm kiếm và thay thế đơn giản) hoặc có thể chuyển từ một tiêu chuẩn ostream thành Boost.Iostreams filtering stream để thực hiện chuyển đổi cho bạn.

+1

+1 cho giải pháp Boost.IOStreams. Cụ thể hơn, sử dụng newline_filter: http://www.boost.org/doc/libs/1_40_0/libs/iostreams/doc/index.html?path=4.2.10.1 –

+0

Có thể đã đi tuyến đường này (vẫn có thể nếu macro trở nên cồng kềnh để duy trì) nhưng chúng tôi có một hệ thống ngốc nghếch để tăng pkgs tại nơi làm việc, và tôi sẽ phải báo lỗi một người nào đó đi qua một số rigmarole để đưa nó vào bàn điều khiển của tôi. –

9

std::endl là cơ bản:

std::cout << "\n" << std::flush; 

Vì vậy, chỉ cần sử dụng "\r\n" thay vào đó và bỏ qua tuôn ra. Nó cũng nhanh hơn thế!

Từ các tập tin tiêu đề ostream trên endl:

thao túng này thường được sử dụng lẫn lộn khi một dòng mới đơn giản là mong muốn, dẫn đến hiệu suất đệm nghèo.

+5

Nếu bạn làm điều đó, đừng quên để mở luồng ở chế độ nhị phân - nếu không, nếu bạn đã từng chuyển mã này sang Windows, bạn sẽ nhận được '\ r \ r \ n' trong đầu ra (vì bản thân' \ n' sẽ được mở rộng thành '\ r \ n 'cho luồng văn bản). –

+0

Điều này sẽ không được chuyển sang Windows, tôi không nghĩ vậy. Có lẽ chúng tôi không thể xử lý việc cấp phép. lol –

+0

+1 - Thông tin tốt về trình điều khiển endl. Tôi sẽ sử dụng nó ít thường xuyên hơn. –

2

Bạn không nên sử dụng \ r \ n. Chỉ cần sử dụng \ n, nhưng sau đó mở luồng ở chế độ "văn bản", chế độ này sẽ thực hiện chuyển đổi cho bạn. Bạn có thể không quan tâm đến nhiều nền tảng, nhưng đây là cách chính thức để thực hiện nó.

Bằng cách đó, cùng một mã sẽ thoát ra \ n trên Unix, \ r \ n trên cửa sổ và \ r trên mac.

+5

Ngoài ra, không sử dụng MS Notepad – Cogwheel

+0

Chương trình tạo tệp văn bản sẽ * luôn * được chạy trên nền tảng Linux và nó sẽ không chạy trên Win/Mac. Các máy đọc tệp văn bản sẽ chạy hệ điều hành của người tiêu dùng (Windows, Mac, Linux). –

+5

Bạn đã thực sự đọc câu hỏi chưa? – mch

4

Windows Notepad là khá nhiều chỉ Chương trình Windows bạn sẽ thấy rằng không xử lý tệp LF chỉ đúng cách. Hầu như mọi thứ khác (bao gồm WordPad) chỉ xử lý các tệp LF-only.

Sự cố này là lỗi trong Notepad.

+0

Khách hàng của chúng tôi có thể chỉ cần nhấp đúp vào tệp, vì vậy chúng tôi sẽ có lòng thương xót của bất kỳ ứng dụng nào đã đăng ký chính nó tại thời điểm trên máy của họ. Có khả năng Notepad mặc định trên Windows. –

+0

tạo html thay thế? – ebo

+3

Nếu bạn phải tạo tệp có đuôi dòng CRLF, hãy chạy (các) tệp đầu ra thông qua bộ lọc độc lập với chính chương trình của bạn. Bạn có thể tìm thấy loại bộ lọc này một cách dễ dàng, tìm kiếm 'unix2dos' hoặc một cái gì đó tương tự. Điều này sẽ giữ logic nền tảng cụ thể này khỏi chương trình của bạn. –

0

Đây là giải pháp cho vấn đề của tôi.Đó là một chút của một mash-up của tất cả các thông tin được cung cấp trong các câu trả lời:

  1. tôi đã tạo một macro trong một file win_endl.h cho newline tôi muốn:

    #define win_endl "\r\n" 
    
  2. Sau đó, tôi đã tìm kiếm và thay thế:

    [email protected]\_machine > sed -i 's/std::endl/win_endl' * 
    

và đảm bảo tất cả các file của tôi bao gồm win_endl.h.

+0

Đây thực sự không phải là giải pháp nếu bạn đang sử dụng chế độ văn bản, vì "\ n" được dịch thành một chuỗi cuối dòng cụ thể của nền tảng. Trên Linux, "\ n" ánh xạ trực tiếp đến ký tự LF. Nhưng nếu bạn chạy mã này trên Windows, bạn sẽ thấy CR-CR-LF vì "\ n" ánh xạ tới CR-LF trên Windows. –

+0

@Brian Neal - Tốt. –

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