当我阅读K& R的C编程语言第176页时,我非常兴奋。我找到了struct FILE的所有成员(我正在搜索),并且知道事情是如何工作的真棒。但猜猜是什么,gcc抱怨,错误:'FILE'没有名为'fd'的成员。这意味着现在情况发生了变化,我用Google搜索但找不到。请帮助,提前谢谢。
我可以使用fileno()来获取文件描述符,但我讨厌在抽象级别上工作。
int
main ( int argc, char **argv ){
FILE *fp = fopen ("ct.c", "r");
printf ("%i", fp->fd);
return 0;
}
答案 0 :(得分:13)
您需要查看C库的源代码。
既然你提到了gcc和Linux,那么你可能正在使用GNU libc,它当然是免费软件。
/* 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
是一个不透明的类型,就像它说的那样。
答案 1 :(得分:1)
内部成员会根据您的编译器进行更改
正如unwind所说,您应该查看编译器的库代码(在您的情况下,GCC,它使用glibc)。
fileno"功能"实际上是一个宏,并在MinGW(在stdio.h中)中定义,如下所示:
#define fileno(__F) ((__F)->_file)
请注意,MinGW基于GCC,不应该存在兼容性问题。
由于它是一个宏,你应该可以通过搜索" #define fileno"来在标准库中找到它。在您的包含文件夹中。它很可能在stdio.h头文件中定义。
另外,要回答您的原始问题,以下是GCC / MinGW中stdio.h中定义的FILE的内部成员:
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
tldr:在minGW / GCC中,使用fp-> _file。如果您正在使用其他编译器,请查看其余帖子
答案 2 :(得分:0)
@unwind的答案很好,但我找到了另一个与GCC类Unix系统的解决方法。
不幸的是,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编程语言中尝试实现反射。