2013-10-28 12 views
6

Tôi đang cố gắng viết một hàm trợ giúp có thể được sử dụng để phân tích các số nguyên từ các tệp cấu hình và từ giao thức dựa trên văn bản (được viết bởi máy chứ không phải bởi một con người). Tôi đã đọc How to parse a string to an int in C++? nhưng các giải pháp không giải quyết được tất cả các vấn đề. Tôi muốn điều gì đó (từ ít nhất đến ít quan trọng nhất):Phân tích cú pháp các số nguyên trong C++

  1. Từ chối các giá trị ngoài phạm vi. strtoul và strtoull không hoàn toàn đạt được điều này: được đưa ra một dấu trừ hàng đầu, giá trị được phủ nhận "trong kiểu trả về". Vì vậy, "-5" được phân tích một cách hạnh phúc và trả về 4294967291 hoặc 18446744073709551611 thay vì báo hiệu lỗi.
  2. Hãy ở trong ngôn ngữ C, bất kể cài đặt miền địa phương toàn cầu (hoặc thậm chí tốt hơn, hãy cho tôi lựa chọn). Trừ khi có một cách để thiết lập miền địa phương toàn cục trên cơ sở cho mỗi luồng, các quy tắc đó ra strtoul, stoul và boost :: lexical_cast, và chỉ để lại istringstream (nơi người ta có thể thấm nhuần một miền địa phương).
  3. Hợp lý chặt chẽ. Nó chắc chắn không phải chấp nhận dấu rác, và lý tưởng là tôi cũng muốn cấm không gian trắng. Điều đó ngay lập tức làm cho strtol và bất cứ điều gì dựa trên nó một chút vấn đề. Dường như istringstream có thể làm việc ở đây bằng cách sử dụng noskipws và kiểm tra EOF, mặc dù đó có thể chỉ là một lỗi GCC.
  4. Lý tưởng nên kiểm soát một số liệu cơ sở có được giả định là 10 hay không nên được suy ra từ tiền tố 0 hoặc 0x.

Bất kỳ ý tưởng nào về giải pháp? Có cách nào dễ dàng để bọc máy phân tích cú pháp hiện có để đáp ứng các yêu cầu này, hay liệu nó sẽ kết thúc là ít công việc hơn để tự viết phân tích cú pháp?

+0

Nếu được viết bằng máy thì tại sao các giá trị nằm ngoài phạm vi? – andre

+1

có vẻ như bạn cần phát triển riêng của mình. hoặc tìm một thư viện tùy chỉnh –

+1

@andre Phạm vi xác nhận là nhiều hơn cho việc phân tích cú pháp tệp cấu hình (được viết bởi một con người). Nhưng nó cũng thận trọng để xác nhận bất kỳ dữ liệu nhận được qua mạng. –

Trả lời

1

Có một số lỗi nhanh, phân tích cú pháp như bình thường (không mạnh) và thực hiện một số kiểm tra nhỏ trong đầu vào (ví dụ: nếu phân tích cú pháp một số không âm, hãy kiểm tra xem ký tự đó không có ký tự '-').

Kiểm tra cuối cùng về độ mạnh là chuyển đổi số nguyên về văn bản và kiểm tra xem văn bản đầu vào và văn bản đầu ra có giống nhau không. Khi làm việc trong phiên bản văn bản, bạn có thể thư giãn mọi thứ, như chấp nhận số 0 hoặc dấu cách hàng đầu.

1

Bạn về cơ bản muốn có khía cạnh num_get<char> của ngôn ngữ C. Nó hơi phức tạp, vì vậy hãy xem this example. Về cơ bản, bạn phải gọi use_facet<num_get<char,string::iterator> > (locale::classic).get(begin, end, ... , outputValue).

+0

Điều này về cơ bản giống như sử dụng istringstream, vì đó là những gì nhà điều hành >> sử dụng dưới mui xe. Có thể có một số giảm chi phí, nhưng nó vẫn chấp nhận các giá trị âm và kết thúc tốt đẹp chúng. –

+0

@BruceMerry: Nó thực sự cắt bỏ chi phí; nó không giống như có nhiều triển khai riêng biệt dưới mui xe. Đối với các số âm, hãy kiểm tra xem nó có làm tròn không: bạn có thể lấy lại chuỗi gốc không? – MSalters

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