2011-07-14 31 views
6

Đặc điểm kỹ thuật cho strtol phân chia khái niệm chuỗi đầu vào thành "khoảng trắng ban đầu", "chuỗi chủ đề" và "chuỗi cuối cùng" và xác định "chuỗi chủ đề" là:Ngôn ngữ khó hiểu trong đặc điểm kỹ thuật của strtol, et al

chuỗi dài nhất ban đầu của chuỗi đầu vào, bắt đầu bằng ký tự không-khoảng trắng đầu tiên có dạng mong muốn. Chuỗi chủ đề không chứa ký tự nếu chuỗi đầu vào trống hoặc chứa toàn bộ các ký tự khoảng trống hoặc nếu ký tự dấu cách trắng đầu tiên không phải là ký hiệu hoặc chữ cái hoặc chữ số được phép.

Tại một thời gian tôi nghĩ rằng "dài nhất dãy ban đầu" kinh doanh là tương tự như cách scanf công trình, nơi "[email protected]" sẽ quét như "0x", một trận đấu thất bại, tiếp theo là "@" như nhân vật chưa đọc tiếp theo. Tuy nhiên, sau một số cuộc thảo luận, tôi chủ yếu tin rằng strtol xử lý chuỗi dài nhất ban đầu có dạng mong đợi, không phải là chuỗi ban đầu dài nhất là chuỗi ban đầu của một số chuỗi có thể có của biểu mẫu dự kiến.

gì vẫn khó hiểu tôi là ngôn ngữ này trong đặc tả:

Nếu chuỗi chủ đề là rỗng hoặc không có các hình thức dự đoán, không có chuyển đổi được thực hiện; giá trị của str được lưu trữ trong đối tượng được trỏ tới bởi endptr, miễn là endptr không phải là một con trỏ null.

Nếu chúng tôi chấp nhận định nghĩa chính xác của "chuỗi chủ đề", không có thứ gì như chuỗi chủ đề không trống không có dạng mong muốn, thay vào đó (để tránh sự thừa và nhầm lẫn) văn bản chỉ nên đọc:

Nếu chuỗi chủ đề trống, không có chuyển đổi nào được thực hiện; giá trị của str được lưu trữ trong đối tượng được trỏ tới bởi endptr, miễn là endptr không phải là một con trỏ null.

Có ai có thể làm rõ những vấn đề này cho tôi không? Có lẽ một liên kết đến các cuộc thảo luận trong quá khứ hoặc bất kỳ báo cáo lỗi nào có liên quan sẽ hữu ích.

+1

Và một ví dụ tiêu chuẩn đơn giản sẽ xóa mọi thứ ... –

+1

Thật vậy. Tôi có một cảm giác về những vấn đề như thế này, ủy ban đã thực sự cố gắng tránh được rõ ràng vì sợ mở một cuộc tranh cãi về cách nó sẽ hoạt động ... –

Trả lời

1

Các POSIX spec for strtol có vẻ là rõ ràng hơn:

Những chức năng có trách nhiệm chuyển đổi các phần ban đầu của chuỗi được trỏ đến bởi str đến một loại đại diện lâu dài và lâu dài, tương ứng. Thứ nhất, họ phân hủy chuỗi đầu vào thành ba phần:

  1. Một ban đầu, có thể trống rỗng, chuỗi các ký tự trắng-không gian (theo quy định của isspace())

  2. Một chuỗi đối tượng hiểu là một số nguyên được biểu thị bằng một số cơ số được xác định bởi giá trị của cơ số

  3. Chuỗi cuối cùng của một hoặc nhiều ký tự không được công nhận, bao gồm ký tự kết thúc NUL của chuỗi đầu vào.

Sau đó, họ sẽ cố gắng chuyển đổi chuỗi chủ đề thành số nguyên và trả về kết quả.

Nhưng tất nhiên, nó không phải là quy chuẩn và "chống tiêu chuẩn ISO C".

+0

Tôi đã đọc phiên bản POSIX của spec. :-) –

+0

Bản sửa đổi của POSIX? Có lẽ họ đã làm rõ từ ngữ? – Nemo

+0

2008, cùng một tài khoản bạn đã liên kết. –

3

Tôi nghĩ rằng ngôn ngữ C99 là khá rõ ràng:

Chuỗi đối tượng được định nghĩa là dãy ban đầu dài nhất của chuỗi đầu vào, bắt đầu với nhân vật không phải da trắng không gian đầu tiên, đó là của dạng mong đợi.

Cho "[email protected]", "[email protected]" không có dạng mong muốn; "0x" không thuộc dạng mong đợi; do đó "0" là chuỗi dài nhất ban đầu có dạng mong đợi.

Tôi đồng ý rằng điều này có nghĩa là bạn không thể có một chuỗi đối tượng không có sản phẩm nào mà không có dạng mong đợi - trừ khi bạn giải thích như sau:

Trong ngoài "C" miền địa phương, thêm locale- đối tượng cụ thể biểu mẫu trình tự có thể được chấp nhận.

... như cho phép ngôn ngữ xác định các dạng có thể khác mà chuỗi chủ đề có thể có, tuy nhiên không phải là "dạng mong muốn".

Từ ngữ trong đoạn cuối cùng có vẻ chỉ là "vành đai và niềng răng".

+0

Tôi quan tâm đến cách bạn nghĩ người ta có thể chen lấn xung quanh yêu cầu với mệnh đề ngôn ngữ .. :-) –

2

Nó có thể là dễ hiểu nếu bạn bắt đầu tại §7.20.1.4 (Các strtol, strtoll, strtoul, và chức năng strtoull) ¶2 của tiêu chuẩn C99, thay vì ¶4:

¶2 Các hàm strtol, strtoll, strtoul, và strtoull chuyển đổi phần ban đầu của chuỗi được trỏ tới bởi nptr thành int dài, dài dài int, không ký hiệu số long int, và unsigned long long int đại diện, tương ứng. Đầu tiên, chúng phân tách chuỗi đầu vào thành ba phần: một chuỗi đầu tiên, có thể trống, ký tự trắng (như được chỉ định bởi hàm isspace), một chuỗi chủ đề giống như một số nguyên được biểu diễn trong một số cơ số được xác định bởi giá trị cơ sở và một chuỗi cuối cùng là của một hoặc nhiều ký tự không được công nhận, bao gồm cả ký tự kết thúc null của chuỗi đầu vào. Sau đó, họ cố chuyển đổi chuỗi chủ đề thành số nguyên và trả lại kết quả.

¶3 Nếu giá trị cơ sở bằng không, thì biểu mẫu dự kiến ​​của chuỗi chủ đề là hằng số nguyên như được mô tả trong 6.4.4.1, được đặt trước bằng dấu trừ hoặc dấu trừ, nhưng không bao gồm số nguyên hậu tố. Nếu giá trị của cơ sở nằm trong khoảng từ 2 đến 36 (bao gồm), thì dạng mong đợi của chuỗi chủ đề là một chuỗi các chữ cái và chữ số đại diện cho số với cơ số được chỉ định bởi cơ sở, tùy chọn trước dấu cộng hoặc dấu trừ, nhưng không bao gồm hậu tố số nguyên. Các chữ cái từ (hoặc A) đến z (hoặc Z) là được mô tả các giá trị từ 10 đến 35; chỉ các chữ cái và chữ số có giá trị được gán ít hơn so với các chữ cái được phép. Nếu giá trị của cơ sở là 16, các ký tự 0x hoặc 0X có thể tùy chọn trước chuỗi các chữ cái và chữ số, sau dấu nếu có.

¶4 Chuỗi đối tượng được định nghĩa là dãy ban đầu dài nhất của chuỗi đầu vào, ...

Đặc biệt, ¶3 làm rõ những gì một chuỗi chủ đề là.

1

Tôi hoàn toàn đồng ý với đánh giá của bạn: Theo định nghĩa, tất cả các chuỗi chủ đề không trống có dạng mong muốn, vì vậy từ ngữ của tiêu chuẩn không rõ ràng.

Trong trường hợp các chức năng chuyển đổi dấu chấm động, có sai lầm ngớ ngẩn khác (C99: TC3 phần 7.20.1.3, §3):

[...] Chuỗi đối tượng được định nghĩa là ban đầu dài nhất chuỗi của chuỗi đầu vào, bắt đầu bằng ký tự đầu tiên không phải là khoảng trắng, đó là dạng mong đợi. Chuỗi chủ đề không chứa ký tự nếu chuỗi đầu vào không thuộc dạng được mong đợi.

Điều này ngụ ý rằng toàn bộ chuỗi đầu vào phải có hình thức dự đoán, đánh bại mục đích của tham số endptr. Người ta có thể lập luận rằng dạng mong đợi cho chuỗi đầu vào khác với dạng mong đợi cho chuỗi chủ đề, nhưng nó vẫn còn khá khó hiểu.

Bạn cũng chính xác rằng ngữ nghĩa của strto*()*scanf() họat động của các hàm khác nhau: Nếu cả hai khớp nhau, chúng sẽ luôn đồng ý về giá trị và tiêu thụ cùng một số ký tự (và bất kỳ hiện thực libc nào mà chúng không bị hỏng, bao gồm cả newlib và glibc lần cuối tôi kiểm tra), nhưng *scanf() bổ sung không khớp với các trường hợp cần quay lại nhiều ký tự, như trong ví dụ "[email protected]""1.0e+".

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