2013-06-20 80 views
7

當我讀K & R的C編程語言第176頁時,我非常興奮。我找到了struct FILE的所有成員(我正在尋找它),並且知道它是如何工作的。但猜猜,gcc抱怨,錯誤:'FILE'沒有名爲'fd'的成員。這意味着事情現在已經改變了,我搜索了一下但是找不到。請幫助,提前謝謝。我想知道struct FILE的內部成員,最新的

我可以使用fileno()來獲取文件描述符,但我討厭在抽象層面上工作。

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

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

    return 0; 
} 
+0

給我們一些代碼,請看看你錯在哪裏 – 3wic

+2

如果你真的想知道它是如何工作的,請閱讀libc的源代碼(https://www.gnu.org/software/libc/)。瞭解成員並不會在表面層面上有所幫助。另外,你可能看不到任何FILE *的成員,因爲它是一個不透明的指針。 https://en.wikipedia.org/wiki/Opaque_pointer沒有理由使用代碼來了解FILE *中的內容,那麼爲什麼還要給它們一個可能性呢?抽象是好的。如果您使用FILE :: fd並且他們決定更改它的名稱,那麼您的代碼將全部中斷。如果您使用fileno,則不會中斷。 – Corbin

+3

@Corbin謝謝你的這些鏈接,yeah抽象是很好的,當你寫代碼,但不是當你想了解一些東西:D – dimSutar

回答

9

你需要看看你的C庫的源代碼。

既然您提到了gcc和Linux,那麼您可能使用的是GNU libc,這當然是免費軟件。

This file說:

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

而且this file聲明_IO_FILE結構:

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 
}; 

機會是,上述特徵,從一個 「真正的」 產品質量圖書館來了,要稍微比更復雜在K & R.中使用的示例。當然,您不能使用,因爲它是庫內部的,並且FILE就像它說的那樣,它是一種不透明的類型。

0

@unwind的答案很好,但是我發現了另一種類似於Unix的類似GCC的系統的解決方法。

不幸的是,C不支持反射(Reflection support in C),但您可以解析輸出C預處理器。 shell腳本的


源代碼

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 

輸出

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)]; 

}; 

這一決定是不很細膩,而是在C企圖實現反射編程語言年齡。