C-style file input/output—file seeking—(std::ftell,std::fgetpos,std::fseek,std::fsetpos,std::rewind)

The C I/O subset of the C++ standard library implements C-style stream input/output operations. The <cstdio> header file provides general file support and provides functions with narrow and multibyte character input/output capabilities, while the <cwchar> header file provides functions with wide character input/output capabilities. 

File location

Returns the current file position indicator

std::ftell

long ftell( std::FILE* stream );

Returns the current value of the file position indicator for file stream stream.

If the stream was opened in binary mode, the value obtained by this function is the number of bytes from the beginning of the file.

If the stream is opened in text mode, the return value of this function is unspecified and is only meaningful as input to std::fseek.

Parameters

stream The file stream to be checked

Return value

File location indicator on success, -1L on failure. errno is also set on failure.

Get file location indicator

std::fgetpos

int fgetpos( std::FILE* stream, std::fpos_t* pos );

Gets the file position indicator and current parsing status (if one exists) of the file stream stream and stores them in the object pointed to by pos. The stored value is only meaningful as input to std::fsetpos.

Parameters

stream File stream to be checked
pos Pointer to the fpos_t object to store the file position indicator

Return value

?0? on success, non-zero otherwise. Also sets errno on failure.

Move the file position indicator to the specified position in the file

std::fseek

int fseek( std::FILE* stream, long offset, int origin );

Sets the file position indicator of the file stream stream to the value pointed to by offset.

If the stream is opened in binary mode, the new position is exactly after the start of the file (if origin is SEEK_SET) or after the current file position (if origin code> is SEEK_CUR), or offset bytes after the end of the file (if origin is SEEK_END). There is no requirement for binary streams to support SEEK_END, especially whether to output additional null bytes.

If the stream is opened in text mode, the only supported offset values are zero (which can be used for any origin) and those previously associated with the same The return value of a call to std::ftell on a file’s stream (only available with SEEK_SET’s origin).

If stream is wide-oriented, restrictions on text and binary streams apply together (allowing results from std::ftell with SEEK_SET, and allowing zero offsets relative to SEEK_SET and SEEK_CUR but not SEEK_END) .

In addition to changing the file position indicator, fseek also undoes the effects of std::ungetc and clears end-of-file status, if applicable.

If a read or write error occurs, the stream’s error indicator ( std::ferror ) is set without affecting the file position.

Parameters

stream The file stream to be modified
offset Number of characters migrated relative to origin
origin offset. It can have one of the following values: SEEK_SET, SEEK_CUR, SEEK_END

Return value

?0? on success, non-zero otherwise.

Attention

After scanning to a non-end position in a wide stream, the next call to any output function may leave the remaining file contents undefined, for example by outputting a multibyte sequence of different lengths.

For text streams, the only legal values for offset are ?0? (applies to any origin) and the return value of a previous ftell call (applies only to SEEK_SET ).

POSIX allows polling after the end of file. If output occurs after this patrol bit, reads in any gap will return zero bytes. Where the file system supports it, this will create a sparse file.

POSIX also requires that fseek be fflushed first if there is any unwritten data (but whether to restore the migration state is implementation-defined). Standard C++ file streams guarantee flushing and unmigration: std::basic_filebuf::seekoff .

Move the file position indicator to the specified position in the file

std::fsetpos

int fsetpos( std::FILE* stream, const std::fpos_t* pos );

Sets the file position indicator and multibyte parsing status (if any) of the C file stream stream according to the value pointed to by pos.

In addition to establishing a new analysis state and position, calling this function undoes the effects of std::ungetc and clears the end-of-file state if it was set.

If the read or write fails, the stream’s error indicator ( std::ferror ) is set.

Parameters

< /table>

Return value

?0? on success, non-zero otherwise. Also sets errno on failure.

Attention

After searching to a non-end position of a wide stream, the next call to any output function may leave the remaining file contents undefined, for example by outputting a multibyte sequence of different lengths.

Move the file position indicator to the beginning of the file

std::rewind
stream The file stream to be modified
pos Pointer to the fpos_t object obtained from a call to std::fgetpos on the stream associated with the same file

void rewind( std::FILE* stream );

Moves the file position indicator to the beginning of the given file stream.

Function equivalent to std::fseek(stream, 0, SEEK_SET); except that it clears the end-of-file and error indicators.

This function discards any effects from previous calls to ungetc.

Parameters

stream The file stream to be modified

Return value

(none)

Call example 1

#include <cstdio>
#include <cstdint>
#include <vector>
#include <fstream>
#include <cassert>

int main()
{
    std::ofstream("dummy.nfo") << "sample data\\
";


    std::FILE* fp = std::fopen("dummy.nfo", "rb");
    assert(fp);

    std::fseek(fp, 0, SEEK_END); // Seek to the end
    std::size_t filesize = std::ftell(fp);

    std::fseek(fp, 0, SEEK_SET); // Seek to the beginning
    std::vector<uint8_t> buffer(filesize);
    std::fread(buffer.data(), sizeof(uint8_t), buffer.size(), fp);

    std::fclose(fp);
    std::printf("i've read %zi bytes\\
", filesize);
    return 0;
}

Output

Call example 2

#include <cstdio>

int main()
{
    std::FILE *f;
    char ch;
    char str[20];

    f = std::fopen("file.txt", "w");
    for (ch = '0'; ch <= '9'; ch + + )
    {
        std::fputc(ch, f);
    }
    std::fclose(f);


    std::FILE* f2 = std::fopen("file.txt", "r");
    unsigned int size = std::fread(str, 1, 10, f2);
    std::puts(str);
    std::printf("\\
%u\\
", size);

    std::rewind(f2);
    unsigned int size2 = std::fread(str, 1, 10, f2);
    std::puts(str);
    std::printf("\\
%u", size2);
    std::fclose(f2);
    return 0;
}

Output