C文件操作

本文详细介绍了标准C库中关于文件操作的多个函数,包括文件指针定位(fseek、ftell、fgetpos、fsetpos)、文件重置(rewind)、文件读写(fread、fwrite)以及文件打开(fopen)等核心功能。通过具体示例展示了如何使用这些函数实现文件数据的高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fseek

Moves the file pointer to a specified location.

FunctionRequired Header
fseek<stdio.h>

int fseek( FILE *stream, long offset, int origin );
Parameters
stream
Pointer to FILE structure为文件指针
offset
Number of bytes from origin为偏移量,整数表示正向偏移,负数表示负向偏移
origin
Initial position设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
Libraries

All versions of the C run-time libraries.

Return Values

If successful, fseek returns 0. Otherwise, it returns a nonzero value. On devices incapable of seeking, the return value is undefined.

Remarks

The fseek function moves the file pointer (if any) associated with stream to a new location that is offset bytes from origin. The next operation on the stream takes place at the new location. On a stream open for update, the next operation can be either a read or a write. The argument origin must be one of the following constants, defined in Stdio.h:

SEEK_CUR
Current position of file pointer当前位置
SEEK_END
End of file文件结尾
SEEK_SET
Beginning of file文件开头
SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2。

You can use fseek to reposition the pointer anywhere in a file. The pointer can also be positioned beyond the end of the file.fseek clears the end-of-file indicator and negates the effect of any priorungetc calls against stream.

When a file is opened for appending data, the current file position is determined by the last I/O operation, not by where the next write would occur. If no I/O operation has yet occurred on a file opened for appending, the file position is the start of the file.

For streams opened in text mode, fseek has limited use, because carriage return—linefeed translations can causefseek to produce unexpected results. The onlyfseek operations guaranteed to work on streams opened in text mode are:

  • Seeking with an offset of 0 relative to any of the origin values.
  • Seeking from the beginning of the file with an offset value returned from a call toftell.

Also in text mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing,fopen and all related routines check for a CTRL+Z at the end of the file and remove it if possible. This is done because usingfseek and ftell to move within a file that ends with a CTRL+Z may causefseek to behave improperly near the end of the file.

Example
/* FSEEK.C: This program opens the file FSEEK.OUT and
 * moves the pointer to the file's beginning.
 */

#include <stdio.h>

void main( void )
{
   FILE *stream;
   char line[81];
   int  result;

   stream = fopen( "file.txt", "w+" );
   if( stream == NULL )
      printf( "The file fseek.out was not opened\n" );
   else
   {
      fprintf( stream, "The fseek begins here: "
                       "This is the file 'fseek.out'.\n" );
      result = fseek( stream, 23L, SEEK_SET);
      if( result )
         printf( "Fseek failed" );
      else
      {
         printf( "File pointer is set to middle of first line.\n" );
         fgets( line, 80, stream );
         printf( "%s", line );

      }
      fclose( stream );
   }
}


Output
File pointer is set to middle of first line.
This is the file 'fseek.out'.
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2);把fp指针退回到离文件结尾100字节处。

ftell

Gets the current position of a file pointer.获取文件读写指针的当前位置

FunctionRequired Header
ftell<stdio.h>

long ftell( FILE *stream );
Parameters
stream
Target FILE structure
Libraries

All versions of the C run-time libraries.

Return Values

ftell returns the current file position. The value returned byftell may not reflect the physical byte offset for streams opened in text mode, because text mode causes carriage return–linefeed translation. Useftell with fseek to return to file locations correctly. On error,ftell returns –1L. On devices incapable of seeking (such as terminals and printers), or when stream does not refer to an open file, the return value is undefined.

Remarks

The ftell function gets the current position of the file pointer (if any) associated with stream. The position is expressed as an offset relative to the beginning of the stream.

Note that when a file is opened for appending data, the current file position is determined by the last I/O operation, not by where the next write would occur. For example, if a file is opened for an append and the last operation was a read, the file position is the point where the next read operation would start, not where the next write would start. (When a file is opened for appending, the file position is moved to end of file before any write operation.) If no I/O operation has yet occurred on a file opened for appending, the file position is the beginning of the file.

In text mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing,fopen and all related routines check for a CTRL+Z at the end of the file and remove it if possible. This is done because usingftell and fseek to move within a file that ends with a CTRL+Z may causeftell to behave improperly near the end of the file.

Example
/* FTELL.C: This program opens a file named FTELL.C
 * for reading and tries to read 100 characters. It
 * then uses ftell to determine the position of the
 * file pointer and displays this position.
 */

#include <stdio.h>

FILE *stream;

void main( void )
{
   long position;
   char list[100];
   if( (stream = fopen( "ftell.c", "rb" )) != NULL )
   {
      /* Move the pointer by reading data: */
      fread( list, sizeof( char ), 100, stream );
      /* Get position after read: */
      position = ftell( stream );
      printf( "Position after trying to read 100 bytes: %ld\n",
              position );
      fclose( stream );
   }
}

Output
Position after trying to read 100 bytes: 100
ftell() 经常和 fseek() 一起使用,首先将文件的位置指针移到文件的末尾,然后调用函数 ftell() 获得当前位置相对于文件首的位移,该位移值等于文件所含字节数。如利用 ftell() 可以方便地获取一个文件的长:
FILE *fp = fopen("demo.txt","rb");  
fseek(fp, 0L, SEEK_END);
len =ftell(fp)+1;

fgetpos

Gets a stream’s file-position indicator.

FunctionRequired Header
fgetpos<stdio.h>

int fgetpos( 
FILE *stream, 
fpos_t *pos );
Parameters
stream
Target stream
pos
Position-indicator storage
Libraries

All versions of the C run-time libraries.

Return Values

If successful, fgetpos returns 0. On failure, it returns a nonzero value.

Remarks

The fgetpos function gets the current value of the stream argument’s file-position indicator and stores it in the object pointed to by pos. Thefsetpos function can later use information stored inpos to reset the stream argument’s pointer to its position at the timefgetpos was called. Thepos value is stored in an internal format and is intended for use only byfgetpos andfsetpos.

fsetpos

Sets the stream-position indicator.

FunctionRequired Header
fsetpos<stdio.h>

int fsetpos( FILE *stream, const fpos_t *pos );
Parameters
stream
Pointer to FILE structure
pos
Position-indicator storage
Libraries

All versions of the C run-time libraries.

Return Values

If successful, fsetpos returns 0. On failure, the function returns a nonzero value.

Remarks

The fsetpos function sets the file-position indicator for stream to the value ofpos, which is obtained in a prior call tofgetpos against stream. The function clears the end-of-file indicator and undoes any effects ofungetc on stream. After callingfsetpos, the next operation on stream may be either input or output.

//Example
/* FGETPOS.C: This program opens a file and reads
 * bytes at several different locations.
 *
 * Place this code in a file called FGETPOS.C and then 
 * put the file in your project directory.
 */

#include <stdio.h>

void main( void )
{
   FILE   *stream;
   fpos_t pos;
   char   buffer[20];

   if( (stream = fopen( "fgetpos.c", "rb" )) == NULL )
      printf( "Trouble opening file\n" );
   else
   {
      /* Read some data and then check the position. */
      fread( buffer, sizeof( char ), 10, stream );
      if( fgetpos( stream, &pos ) != 0 )
         printf( "fgetpos error" );
      else
      {
         fread( buffer, sizeof( char ), 10, stream );
         printf( "10 bytes at byte %I64d: %.10s\n", pos, buffer );
      }

   /* Set a new position and read more data */
   pos = 140;
   if( fsetpos( stream, &pos ) != 0 )
      printf( "fsetpos error" );

   fread( buffer, sizeof( char ), 10, stream );
   printf( "10 bytes at byte %I64d: %.10s\n", pos, buffer );
   fclose( stream );
   }
}

Output
10 bytes at byte 10: .C: This p
10 bytes at byte 140: .C and the


ftell() 和 fseek() 用长整型表示文件内的偏移 (位置), 因此, 在32位系统偏移量被限制在-2^31 ~ (2^31 - 1)以内。而新的 fgetpos() 和 fsetpos() 函数使用了一个特殊的类型定义 fpos_t 来表示偏移量。这个类型会适当选择, 因此, fgetpos() 和 fsetpos 可以表示任意大小的文件偏移。fgetpos() 和  gsetpos() 也可以用来记录多字节流式文件的状态。

e.g:

    FILE *fp;
    char string[] = "This is a test";
    fpos_t pos;
    /* 以读写方式打开一个名为test.txt的文件 */
    fp = fopen("test.txt", "w+");
    /* 将字符串写入文件 */
    fwrite(string, strlen(string), 1, fp);
    /* 取得指针位置并存入&pos所指向的对象 */
    fgetpos(fp, &pos);
    printf("The file pointer read by fgetpos is at byte %ld\n", pos);
    printf("The file pointer read by ftell is at byte %ld\n", ftell(fp));
    /*重设文件指针的位置*/
    fseek(fp,3,0);
    /* 再次取得指针位置并存入&pos所指向的对象 */
    fgetpos(fp, &pos);
    printf("The file pointer read by fgetpos is at byte %ld\n", pos);
    printf("The file pointer read by ftell is at byte %ld\n", ftell(fp));
    fclose(fp);

rewind

Repositions the file pointer to the beginning of a file.

void rewind( FILE *stream );

RoutineRequired HeaderCompatibility
rewind<stdio.h>ANSI, Win 95, Win NT

For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIBSingle thread static library, retail version
LIBCMT.LIBMultithread static library, retail version
MSVCRT.LIBImport library for MSVCRT.DLL, retail version

Return Value

None

Parameter

stream

Pointer to FILE structure

Remarks

The rewind function repositions the file pointer associated withstream to the beginning of the file. A call torewind is similar to

(void) fseek( stream, 0L, SEEK_SET );

However, unlike fseek, rewind clears the error indicators for the stream as well as the end-of-file indicator. Also, unlikefseek,rewind does not return a value to indicate whether the pointer was successfully moved.

To clear the keyboard buffer, use rewind with the stream stdin, which is associated with the keyboard by default.

Example

/* REWIND.C: This program first opens a file named
 * REWIND.OUT for input and output and writes two
 * integers to the file. Next, it uses rewind to
 * reposition the file pointer to the beginning of
 * the file and reads the data back in.
 */

#include <stdio.h>

void main( void )
{
   FILE *stream;
   int data1, data2;

   data1 = 1;
   data2 = -37;

   if( (stream = fopen( "rewind.out", "w+" )) != NULL )
   {
      fprintf( stream, "%d %d", data1, data2 );
      printf( "The values written are: %d and %d\n", data1, data2 );
      rewind( stream );
      fscanf( stream, "%d %d", &data1, &data2 );
      printf( "The values read are: %d and %d\n", data1, data2 );
      fclose( stream );
   }
}

Output

The values written are: 1 and -37
The values read are: 1 and -37

fread

Reads data from a stream.

FunctionRequired Header
fread<stdio.h>

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
Parameters
buffer
Storage location for data为接收数据的地址
size
Item size in bytes为一个单元的大小
count
Maximum number of items to be read为单元个数
stream
Pointer to FILE structure为文件流

每次从stream中最多读取count个单元,每个单元大小为size个字节,将读取的数据放到buffer;文件流的位置指针后移 size * count 字节。
Libraries

All versions of the C run-time libraries.

Return Values

fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use thefeof orferror function to distinguish a read error from an end-of-file condition. If size or count is 0,fread returns 0 and the buffer contents are unchanged.返回实际读取的单元个数。如果小于count,则可能文件结束或读取出错;可以用ferror()检测是否读取出错,用feof()函数检测是否到达文件结尾。如果size或count为0,则返回0。

Remarks

The fread function reads up to count items of size bytes from the input stream and stores them in buffer. The file pointer associated with stream (if there is one) is increased by the number of bytes actually read. If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value. The file-pointer position is indeterminate if an error occurs. The value of a partially read item cannot be determined.

Example
/* FREAD.C: This program opens a file named FREAD.OUT and
 * writes 25 characters to the file. It then tries to open
 * FREAD.OUT and read in 25 characters. If the attempt succeeds,
 * the program displays the number of actual items read.
 */

#include <stdio.h>

void main( void )
{
   FILE *stream;
   char list[30];
   int  i, numread, numwritten;

   /* Open file in text mode: */
   if( (stream = fopen( "file.out", "w+t" )) != NULL )
   {
      for ( i = 0; i < 25; i++ )
         list[i] = (char)('z' - i);
      /* Write 25 characters to stream */
      numwritten = fwrite( list, sizeof( char ), 25, stream );
      printf( "Wrote %d items\n", numwritten );
      fclose( stream );

   }
   else
      printf( "Problem opening the file\n" );

   if( (stream = fopen( "fread.out", "r+t" )) != NULL )
   {
      /* Attempt to read in 25 characters */
      numread = fread( list, sizeof( char ), 25, stream );
      printf( "Number of items read = %d\n", numread );
      printf( "Contents of buffer = %.25s\n", list );
      fclose( stream );
   }
   else
      printf( "File could not be opened\n" );
}
Output
Wrote 25 items
Number of items read = 25
Contents of buffer = zyxwvutsrqponmlkjihgfedcb
    FILE *pFile = fopen("1.txt", "r") ;  
    char *pBuf ;                    // 声明一个堆数据缓冲区  
    fseek(pFile, 0, SEEK_END) ;     // 将文件指针移动到该文件的末尾  
    int iLength = ftell(pFile) ;     // 通过ftell()函数读取文件指针的位置返回该文件的大小  
    pBuf = new char[iLength + 1] ;   // 实例化该堆数据缓冲区, 大小是文件的大小+1  
    rewind(pFile) ;                 // 将文件指针移动到该文件的开始处  
    fread(pBuf, 1, iLength, pFile) ; //   
    pBuf[length] = 0 ;              // 将堆数据缓冲区的最后一个字节置为0, 防止打印时出现乱码   
    fclose(pFile) ; 

fwrite

Writes data to a stream.

FunctionRequired Header
fwrite<stdio.h>

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
Parameters
buffer
Pointer to data to be written为一个指针,对fwrite来说,是要输出数据的地址
size
Item size in bytes为要写入的字节数
count
Maximum number of items to be written为要进行写入size字节的数据项的个数
stream
Pointer to FILE structure为目标文件指针
Libraries

All versions of the C run-time libraries.

Return Values

fwrite returns the number of full items actually written, which may be less than count if an error occurs. Also, if an error occurs, the file-position indicator cannot be determined.

Remarks

The fwrite function writes up to count items, of size length each, from buffer to the output stream. The file pointer associated with stream (if there is one) is incremented by the number of bytes actually written. If stream is opened in text mode, each carriage return is replaced with a carriage-return – linefeed pair. The replacement has no effect on the return value.

e.g:

struct mystruct
{
    char chArr[2];
    char ch;	
};
int main(void)
{
    // 定义一个文件指针, 并调用fopen()函数返回一个文件指针  
    FILE* pFile;
   pFile = fopen("file.txt","w+");  // 打开
   if(pFile == NULL) // 打开文件失败
    {
        printf("the file is opeaned error!\n");
   }
    struct mystruct s;
    s.chArr[0] = 'A';
    s.chArr[1] = '1';
    s.ch = 'A';
    fseek(pFile, 0, SEEK_SET);      // 设置文件指针的位置, 后面的fwrite()函数将从重新设定的文件指针处开始写入数据  
   fwrite(&s, sizeof(s), 1, pFile); // 将结构体写入file.txt文件
    fflush(pFile);             // 刷新缓冲区, 不管此时缓冲区中数据的多少, 都将在执行此行代码后将缓冲区中的数据写入到磁盘中  
    fclose(pFile);             // 关闭文件指针后, 输入流缓冲区的数据将写入到磁盘中, 一般情况下, 对文件操作完毕后, 应关闭相应的文件指针 
    return 0;
}
//out put A1A    

fopen, _wfopen

Open a file.

FunctionRequired Header
fopen<stdio.h>
_wfopen<stdio.h>

FILE *fopen( const char *filename, const char *mode );
FILE *_wfopen( const wchar_t *filename, const wchar_t *mode );
Parameters
filename
Filename
mode
Type of access permitted
Libraries

All versions of the C run-time libraries.

The c, n, and t mode options are Microsoft extensions for fopen and should not be used where ANSI portability is desired.

Return Values

Each of these functions returns a pointer to the open file. A null pointer value indicates an error.

Remarks

The fopen function opens the file specified by filename. _wfopen is a wide-character version of fopen; the arguments to_wfopen are wide-character strings._wfopen andfopen behave identically otherwise.

Generic-Text Routine Mappings
TCHAR.H Routine_UNICODE Defined
_tfopen_wfopen

The character string mode specifies the type of access requested for the file, as follows:

"r"
Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
"w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
"a"
Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn’t exist.
"r+"
Opens for both reading and writing. (The file must exist.)
"w+"
Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.
"a+"
Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.

When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned usingfseek, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.

The "a" mode does not remove the EOF marker before appending to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. The "a+" mode does remove the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file. The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.

When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an interveningfflush,fsetpos, or fseek operation. The current position can be specified for thefsetpos orfseek operation, if desired.

In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:

t
Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing with "a+", fopen checks for a CTRL+Z at the end of the file and removes it, if possible. This is done because using fseek and ftell to move within a file that ends with a CTRL+Z, may cause fseek to behave improperly near the end of the file.

Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters. For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters.

b
Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.

If t or b is not given in mode, the default translation mode is defined by the global variable _fmode. If t or b is prefixed to the argument, the function fails and returns NULL.

For more information about using text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.

c
Enable the commit flag for the associated filename so that the contents of the file buffer are written directly to disk if either fflush or _flushall is called.
n
Reset the commit flag for the associated filename to “no-commit.” This is the default.
Example
/* FOPEN.C: This program opens files named "data"
 * and "data2".It  uses fclose to close "data" and
 * _fcloseall to close all remaining files.
 */

#include <stdio.h>

FILE *stream, *stream2;

void main( void )
{
   int numclosed;

   /* Open for read (will fail if file "data" does not exist) */
   if( (stream  = fopen( "data", "r" )) == NULL )
      printf( "The file 'data' was not opened\n" );
   else
      printf( "The file 'data' was opened\n" );

   /* Open for write */
   if( (stream2 = fopen( "data2", "w+" )) == NULL )
      printf( "The file 'data2' was not opened\n" );
   else
      printf( "The file 'data2' was opened\n" );

   /* Close stream */
   if( fclose( stream ) )
      printf( "The file 'data' was not closed\n" );

   /* All other files are closed: */
   numclosed = _fcloseall( );
   printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
Output
The file 'data' was opened
The file 'data2' was opened
Number of files closed by _fcloseall: 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值