2009-10-26 33 views
6

EOF luôn có âm?EOF luôn là tiêu cực?

Tôi đang nghĩ đến việc viết một hàm đọc từ tiếp theo trong đầu vào và trả về số dòng mà từ đó được tìm thấy trong hoặc EOF nếu đã kết thúc đầu vào. Nếu EOF không nhất thiết là tiêu cực, hàm sẽ không chính xác.

+1

Tại sao bạn thậm chí cần trả lại EOF từ chức năng của riêng bạn? Chỉ cần xác định hàm của bạn là "trả về số dòng mà từ đó được tìm thấy, hoặc -1 nếu đã kết thúc đầu vào". Điều đó nói rằng, nhiều nguồn (ví dụ: Hoàn thành mã) cảnh báo chống lại các giá trị trả về trộn với mã lỗi. –

+0

Phải, đó là một lựa chọn khả thi và hoàn toàn khả thi. Tuy nhiên, tôi nghĩ EOF sẽ rõ ràng hơn. – Ree

Trả lời

10

Có, EOF luôn là số âm.

Tiêu chuẩn nói:

7,19 Input/output
7.19.1 Giới thiệu

3 macro là [...] EOF mà mở rộng thành hằng số nguyên biểu thức, với loại int và giá trị âm, được trả về bởi một số chức năng để chỉ ra kết thúc tệp, nghĩa là không nhập thêm từ luồng;

Lưu ý rằng không có vấn đề gì với "đồng bằng" char đang được ký. Các hàm <stdio.h> đối phó với char s, đặc biệt đúc các ký tự thành unsigned char và sau đó đến int, sao cho tất cả các ký tự hợp lệ đều có giá trị dương. Ví dụ:

int fgetc(FILE *stream) 

7.19.7.1
... chức năng fgetc có được rằng nhân vật như một char unsigned chuyển đổi sang một int ...

+3

Có một vấn đề nếu 'sizeof (char) == sizeof (int)', mặc dù ngay cả việc truyền qua 'unsigned char' sẽ không nhất thiết giữ tất cả các giá trị' char' hợp lệ. May mắn thay điều này là tương đối hiếm. –

+0

Đó chỉ là vấn đề nếu bạn giả định sai giá trị âm luôn là EOF ('if (ch <0)/* EOF được phát hiện * /;') hoặc nếu "bộ ký tự thực thi" sử dụng hết tất cả các giá trị từ 'INT_MIN' đến' 0' trong trường hợp giá trị 'EOF' giống với giá trị của một ký tự hợp lệ. – pmg

15

EOF luôn là == EOF. Đừng thừa nhận bất cứ điều gì khác.

Trong lần đọc thứ hai của tiêu chuẩn (và theo một số nhận xét khác ở đây) có vẻ như EOF luôn âm - và cho việc sử dụng được chỉ định trong câu hỏi này (số dòng hoặc EOF) nó sẽ hoạt động. Những gì tôi có nghĩa là để cảnh báo chống lại (và vẫn làm) là giả định các ký tự là tích cực và EOF là tiêu cực.

Hãy nhớ rằng nó có thể cho một tiêu chuẩn phù hợp với thực hiện C có giá trị nhân vật tiêu cực - điều này thậm chí còn được đề cập trong 'C ngôn ngữ lập trình' (K & R). Các ký tự in luôn dương, nhưng trên một số kiến ​​trúc (có thể là tất cả các cổ), các ký tự điều khiển là âm. Tiêu chuẩn C không chỉ rõ thời điểm loại char được ký hoặc chưa ký, và hằng số ký tự duy nhất được đảm bảo có cùng giá trị trên các nền tảng là '\0'.

+0

Bạn có thể thêm một số tham chiếu không? – Guillaume

+6

Điều này không chính xác. Macro EOF ** phải ** mở rộng thành một số nguyên âm, rất tiếc là tôi không có bản sao của tiêu chuẩn để bàn tay vào lúc này. –

+0

Tài liệu tham khảo C thư viện, mà nói rằng phải mất gần như tất cả các thông tin của nó từ tiêu chuẩn ANSI C, nói rằng "EOF là một số nguyên âm mà chỉ ra một kết thúc của tập tin đã đạt được" (http: //www.acm .uiuc.edu/webmonkeys/book/c_guide/2.12.html # biến). Điều đó nói rằng, tôi vẫn sẽ nói rằng đó là phong cách xấu và, trên hết, không cần thiết để giả định EOF là tiêu cực. –

8

Có mà hàm trả về

  • số dòng chữ đã được tìm thấy trong
  • hoặc -1 trong trường hợp khi kết thúc đầu vào đã đạt

Vấn đề được giải quyết, mà không cần để dựa vào bất kỳ giá trị EOF nào. Người gọi có thể dễ dàng kiểm tra cho lớn hơn hoặc bằng-bằng không cho một cuộc gọi thành công, và giả định EOF/IO-lỗi khác.

+0

Thật vậy, đó là một lựa chọn tốt. – Ree

1

EOF là một điều kiện, chứ không phải là giá trị. Giá trị chính xác của sentinel này được thực hiện xác định. Trong nhiều trường hợp, nó là một số âm.

1

Từ wikipedia:

Giá trị thực tế của EOF là một số âm hệ thống phụ thuộc vào, thường -1, đó là đảm bảo được bất bình đẳng đối với bất kỳ mã ký tự hợp lệ.

Nhưng không có tài liệu tham khảo ...

Từ Mã hóa an toàn: Detect and handle input and output errors EOF là tiêu cực nhưng chỉ khi sizeof(int) > sizeof(char).

+0

Wikipedia không hoàn toàn chính xác ở đây. EOF có thể bằng -1 và với ký tự đã ký, một ký tự có thể có giá trị -1 (ví dụ: Ký hiệu đồng euro trong windows-1252). Trường hợp nào là giá trị trả về của '(f) getc' là ký tự tiếp theo được gán cho một ký tự unsigned char và sau đó đến một' int' và điều này không khớp với 'EOF'.Tất nhiên điều này chỉ có thể hoạt động nếu 'sizeof (int)! = Sizeof (char)'. –

2

Từ online draft n1256, 17.9.1.3 :

EOF

mở rộng đến một biểu thức hằng số nguyên, với kiểu int và giá trị âm, được trả về bởi một số hàm để biểu thị kết thúc tệp, nghĩa là không còn nhập từ luồng;

EOF luôn âm, mặc dù không phải lúc nào cũng là -1.

Đối với các vấn đề như thế này, tôi thích tách điều kiện lỗi từ dữ liệu bằng cách trả lại một mã lỗi (SUCCESS, END_OF_FILE, READ_ERROR, vv) như là giá trị trả về của hàm, và sau đó ghi dữ liệu quan tâm đến các thông số riêng biệt, chẳng hạn như

int getNextWord (FILE *stream, char *buffer, size_t bufferSize, int *lineNumber) 
{ 
    if (!fgets(buffer, bufferSize, stream)) 
    { 
    if (feof(stream)) return END_OF_FILE; else return READ_ERROR; 
    } 
    else 
    { 
    // figure out the line number 
    *lineNumber = ...; 
    } 
    return SUCCESS; 
}  
Các vấn đề liên quan