2013-06-06 33 views
6

Tôi đã viết trình đọc/ghi CSV của riêng mình trong C để lưu trữ bản ghi trong cột ký tự trong cơ sở dữ liệu ODBC. Thật không may tôi đã phát hiện ra nhiều trường hợp cạnh mà chuyến đi qua việc thực hiện của tôi, và tôi đã đi đến kết luận vấn đề của tôi là tôi đã không xác định nghiêm ngặt các quy tắc cho CSV. Tôi đã đọc RFC4180, nhưng nó có vẻ không đầy đủ và không giải quyết được sự mơ hồ.Định nghĩa nghiêm ngặt để đọc/ghi tệp CSV

Ví dụ: "" được coi là mã thông báo trống hoặc dấu ngoặc kép? Các dấu ngoặc kép có khớp với bên ngoài hoặc từ trái sang phải không? Tôi phải làm gì với chuỗi đầu vào có dấu nháy đơn chưa từng có? Mớ hỗn độn thực sự bắt đầu khi tôi có các thẻ lồng nhau, tăng gấp đôi ký tự trích dẫn thoát.

Điều tôi thực sự cần là tiêu chuẩn CSV chính xác mà tôi có thể triển khai trong mã. Mỗi khi tôi cảm thấy tôi đã đóng đinh mọi trường hợp góc, tôi tìm thấy một cái khác. Tôi chắc chắn vấn đề này đã được mulled hơn và giải quyết nhiều lần hơn bởi tâm trí cao cấp của tôi, có ai viết một định nghĩa nghiêm ngặt của CSV mà tôi có thể thực hiện trong mã? Tôi nhận ra C không phải là ngôn ngữ lý tưởng ở đây, nhưng tôi không có một sự lựa chọn về trình biên dịch ở giai đoạn này; Tôi cũng không thể sử dụng thư viện của bên thứ ba (trừ khi nó biên dịch với C-90). Boost không phải là một tùy chọn vì trình biên dịch của tôi không hỗ trợ C++. Tôi đã dự tính bỏ CSV cho XML, nhưng nó có vẻ như quá mức cần thiết để lưu trữ một vài mã thông báo trong một bản ghi cơ sở dữ liệu 256 ký tự. Bất kỳ ai đã tạo một thông số CSV chính xác?

+1

http://stackoverflow.com/questions/14115529/parse-csv-file-in-c Thư viện được đề xuất ở đây tuân thủ ANSI C89. – Nobilis

Trả lời

0

Tìm thư viện CSV có thẩm quyền nhất mà bạn tin tưởng và đọc nguồn. CSV không quá phức tạp đến mức bạn sẽ không thể hiểu các quy tắc của nó từ việc đọc toàn diện về triển khai nguồn. Tôi đã hài lòng với Java opencsv. Perl là here, v.v.

1

Không có tiêu chuẩn (xem bài viết của Wikipedia, cụ thể là http://en.wikipedia.org/wiki/Comma-separated_values#Lack_of_a_standard), vì vậy để sử dụng CSV, bạn cần phải tuân theo nguyên tắc chung là bảo thủ trong những gì bạn tạo ra và tự do trong những gì bạn chấp nhận. Cụ thể:

  • Không sử dụng dấu ngoặc kép cho trường trống. Chỉ cần viết một trường trống (hai dấu phân tách liền kề, hoặc dấu phân tách ở vị trí đầu tiên/cuối cùng của dòng).
  • Trích dẫn bất kỳ trường nào có dấu ngoặc kép, dấu phẩy hoặc dòng mới.
+0

Trong khi RFC không phải là một tiêu chuẩn, nó là rất rõ ràng - Tôi thấy không có sự nhầm lẫn trong từ ngữ. Bài viết trên Wikipedia bạn đã liên kết các cuộc trò chuyện về các tệp CSV theo thuật ngữ người dùng - ví dụ, Excel nhóm tất cả các tệp dựa trên văn bản trong CSV và sau đó trình hướng dẫn nhập có thể được sử dụng để chọn dấu tách, v.v. – xxbbcc

+0

Ngoài ra, tôi không nghĩ rằng nó rất lời khuyên tốt để có các quy tắc khác nhau để trích dẫn các giá trị trường khi viết tệp CSV. Nếu tất cả các giá trị trường được trích dẫn, phân tích cú pháp tệp là một vấn đề rất đơn giản. – xxbbcc

+0

@xxbbcc: Như OP đã lưu ý, trích dẫn các trường trống không phải là "bảo thủ trong những gì bạn tạo ra" bởi vì có một sự mơ hồ về cách '' "' được diễn giải. Ngay cả RFC không rõ ràng trừ khi bạn chỉ cần bỏ qua văn bản tiếng Anh của RFC và tuân theo ngữ pháp ABNF. –

0

Theo RFC 4180, các trường phải được phân tích cú pháp từ trái sang phải để diễn giải chính xác câu trích dẫn kép. Trong một số ngữ cảnh, "" là dấu ngoặc kép thoát kép (khi nằm trong trường được trích dẫn), nếu không thì đó là một chuỗi trống hoặc hai dấu ngoặc kép (khi bên trong một giá trị trường trống khác).

Ví dụ, hãy xem xét một tập tin với 4 hồ sơ (1 cột):

"field""value" CRLF 
"" CRLF 
field""value CRLF 
"field value" extra CRLF 
  1. "field""value" - cần được đọc như field"value
  2. "" - cần được đọc như một chuỗi rỗng
  3. field""value - phải được đọc là field""value
  4. "field value" extra - có thể được đọc là field value extra hoặc bạn có thể từ chối nó

Bản ghi 4 thực sự là trường không hợp lệ để bạn có thể chấp nhận hoặc từ chối nó.

Khi bạn bắt đầu đọc một trường, bạn cần kiểm tra xem ký tự đầu tiên có phải là dấu ngoặc kép hay không. Nếu ký tự đầu tiên là dấu ngoặc kép, giá trị trường được trích dẫn và bạn cần phải đọc cho đến khi bạn tìm thấy dấu ngoặc kép đóng không thoát. Trong trường hợp này, bạn có thể bỏ qua các dòng mới và các ký tự dấu phẩy, vì trường được trích dẫn - nó chỉ kết thúc khi bạn mã hóa một dấu ngoặc kép đóng.

Nếu ký tự đầu tiên không phải là dấu ngoặc kép thì tất cả các dấu ngoặc kép trong giá trị trường sẽ được coi là các dấu hai chấm theo nghĩa đen. Trong trường hợp này, bạn đạt đến cuối của trường khi bạn gặp một dấu phẩy hoặc một ký tự dòng mới.

Dựa trên điều này, tôi khuyên bạn nên luôn trích dẫn tất cả các trường khi bạn viết các bản ghi và viết một trình phân tích cú pháp thích hợp để phân tích các bản ghi khi bạn đọc dữ liệu. Bằng cách này, bạn có thể lưu trữ bất kỳ dữ liệu nào trong các tệp CSV của mình (ngay cả văn bản nhiều dòng với các trích dẫn được nhúng) và định dạng của bạn sẽ rõ ràng. Khi đọc tệp CSV, tôi không thể phân tích tất cả các tệp không được phân tích cú pháp chính xác - nếu đây là cơ sở dữ liệu, bạn có thể mong đợi người dùng không gây rối với hồ sơ theo cách thủ công, trừ khi họ biết họ đang làm gì.

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