2013-06-20 2 views
7

Khi tôi đọc pg.176 của ngôn ngữ lập trình C theo K & R, tôi đã rất vui mừng. Tôi tìm thấy tất cả các thành viên của struct FILE (mà tôi đã tìm kiếm) và nó chỉ tuyệt vời để biết mọi thứ hoạt động như thế nào. Nhưng hãy đoán xem, gcc than phiền, lỗi: ‘FILE’ không có thành viên nào có tên ‘fd’. Nó có nghĩa là mọi thứ đã thay đổi ngay bây giờ, tôi googled nhưng không thể tìm thấy. Xin vui lòng giúp đỡ, cảm ơn bạn trước.Tôi muốn biết các thành viên nội bộ của struct FILE, những cái mới nhất

Tôi có thể sử dụng fileno() để lấy bộ mô tả tệp, nhưng tôi ghét làm việc ở mức trừu tượng.

int 
main (int argc, char **argv){ 

    FILE *fp = fopen ("ct.c", "r"); 
    printf ("%i", fp->fd); 

    return 0; 
} 
+0

Hãy cho chúng tôi một số mã để xem bạn đang ở đâu sai – 3wic

+2

Nếu bạn thực sự muốn biết cách hoạt động, hãy đọc nguồn của libc (https://www.gnu.org/software/libc/). Việc biết các thành viên sẽ không phải là tất cả những gì hữu ích dưới một mức độ bề ngoài. Ngoài ra, bạn có thể không thấy bất kỳ thành viên nào của FILE * bởi vì nó là một con trỏ mờ đục. https://en.wikipedia.org/wiki/Opaque_pointer Không có lý do gì để tiêu thụ mã để biết những gì có trong FILE *, vậy tại sao lại khiến họ có khả năng? Tóm tắt là tốt. Nếu bạn đang sử dụng FILE :: fd và họ đã quyết định thay đổi tên của nó, mã của bạn sẽ bị hỏng. Nếu bạn đang sử dụng fileno, không có gì phá vỡ. – Corbin

+3

@Corbin cảm ơn bạn vì những liên kết này, vâng trừu tượng là tốt khi bạn viết mã nhưng không phải khi bạn muốn hiểu một số nội dung: D – dimSutar

Trả lời

9

Bạn cần xem mã nguồn của thư viện C.

Vì bạn đề cập đến gcc và Linux, có thể bạn đang sử dụng GNU libc, đây là phần mềm miễn phí của khóa học.

This file nói:

/* The opaque type of streams. This is the definition used elsewhere. */ 
typedef struct _IO_FILE __FILE; 

this file tuyên bố _IO_FILE cấu trúc:

struct _IO_FILE { 
    int _flags;  /* High-order word is _IO_MAGIC; rest is flags. */ 
#define _IO_file_flags _flags 

    /* The following pointers correspond to the C++ streambuf protocol. */ 
    /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ 
    char* _IO_read_ptr; /* Current read pointer */ 
    char* _IO_read_end; /* End of get area. */ 
    char* _IO_read_base; /* Start of putback+get area. */ 
    char* _IO_write_base; /* Start of put area. */ 
    char* _IO_write_ptr; /* Current put pointer. */ 
    char* _IO_write_end; /* End of put area. */ 
    char* _IO_buf_base; /* Start of reserve area. */ 
    char* _IO_buf_end; /* End of reserve area. */ 
    /* The following fields are used to support backing up and undo. */ 
    char *_IO_save_base; /* Pointer to start of non-current get area. */ 
    char *_IO_backup_base; /* Pointer to first valid character of backup area */ 
    char *_IO_save_end; /* Pointer to end of non-current get area. */ 

    struct _IO_marker *_markers; 

    struct _IO_FILE *_chain; 

    int _fileno; 
#if 0 
    int _blksize; 
#else 
    int _flags2; 
#endif 
    _IO_off_t _old_offset; /* This used to be _offset but it's too small. */ 

#define __HAVE_COLUMN /* temporary */ 
    /* 1+column number of pbase(); 0 is unknown. */ 
    unsigned short _cur_column; 
    signed char _vtable_offset; 
    char _shortbuf[1]; 

    /* char* _save_gptr; char* _save_egptr; */ 

    _IO_lock_t *_lock; 
#ifdef _IO_USE_OLD_IO_FILE 
}; 

Rất có thể rằng ở trên, đến từ một thư viện sản xuất chất lượng "thực", là hơi phức tạp hơn ví dụ được sử dụng trong K & R. Và, tất nhiên, bạn không thể sử dụng điều này vì nó là thư viện nội bộ và FILE là một loại mờ đục, giống như nó nói.

0

Câu trả lời của @unwind là tốt, nhưng tôi tìm thấy một cách giải quyết khác cho các hệ thống giống Unix với GCC.

Thật không may, C không hỗ trợ cho sự phản chiếu (Reflection support in C), nhưng bạn có thể phân tích cú pháp đầu ra bộ tiền xử lý C. đang


Nguồn shell script

setivolkylany$~/Downloads$ cat script.sh 

# a tempfile for source code on the C programming language 
FILE_C=`tempfile` 

# a tempfile for preprocessor`s output 
FILE_I=`tempfile` 

printf "#include \"stdio.h\"\nint main() {return 0;}" > $FILE_C 
cpp $FILE_C > $FILE_I 

# parse content of the tempfile for preprocessor`s output 
# and display only the structure 
print_it=false 
while read line; do 
    if [ "$line" == "struct _IO_FILE {" ]; then 
     print_it=true 
    fi; 
    if [ "$print_it" = true ]; then 
     echo $line 
    fi; 
    if [ "$line" == "};" ]; then 
     print_it=false 
    fi; 
done < $FILE_I 

# clean tempfiles 
rm $FILE_C $FILE_I 

Output

setivolkylany$~/Downloads$ ./script.sh 
struct _IO_FILE { 
int _flags; 




char* _IO_read_ptr; 
char* _IO_read_end; 
char* _IO_read_base; 
char* _IO_write_base; 
char* _IO_write_ptr; 
char* _IO_write_end; 
char* _IO_buf_base; 
char* _IO_buf_end; 

char *_IO_save_base; 
char *_IO_backup_base; 
char *_IO_save_end; 

struct _IO_marker *_markers; 

struct _IO_FILE *_chain; 

int _fileno; 



int _flags2; 

__off_t _old_offset; 



unsigned short _cur_column; 
signed char _vtable_offset; 
char _shortbuf[1]; 



_IO_lock_t *_lock; 
# 293 "/usr/include/libio.h" 3 4 
__off64_t _offset; 
# 302 "/usr/include/libio.h" 3 4 
void *__pad1; 
void *__pad2; 
void *__pad3; 
void *__pad4; 
size_t __pad5; 

int _mode; 

char _unused2[15 chrome-remote-desktop_current_amd64.deb data_structures_algorithms_tutorial.pdf dict-uk_ua-3-5-1.oxt getline.c jquery-3.1.1.min.js ld-linux.so (1).2 ld-linux.so.2 Makefile Portable Microsoft Office 2003.exe Python-3.5.2 script.sh teamviewer_12.0.71510_amd64.deb teamviewer_12.0.71510_i386.deb text_editor.zip sizeof (int) - 4 chrome-remote-desktop_current_amd64.deb data_structures_algorithms_tutorial.pdf dict-uk_ua-3-5-1.oxt getline.c jquery-3.1.1.min.js ld-linux.so (1).2 ld-linux.so.2 Makefile Portable Microsoft Office 2003.exe Python-3.5.2 script.sh teamviewer_12.0.71510_amd64.deb teamviewer_12.0.71510_i386.deb text_editor.zip sizeof (void *) - sizeof (size_t)]; 

}; 

Quyết định này là không rất tinh tế, mà là một thực hiện phản ánh nỗ lực trong C -chương trình lập trình tuổi tác.