C 风格文件输入/输出---文件寻位---(std::ftell,std::fgetpos,std::fseek,std::fsetpos,std::rewind)

C++ 标准库的 C I/O 子集实现 C 风格流输入/输出操作。 <cstdio> 头文件提供通用文件支持并提供有窄和多字节字符输入/输出能力的函数,而 <cwchar>头文件提供有宽字符输入/输出能力的函数。

文件寻位

返回当前文件位置指示器

std::ftell

long ftell( std::FILE* stream );

返回文文件流 stream 的文件位置指示器的当前值。

若流以二进制模式打开,则此函数获得的值是距文件起始的字节数。

若流以文本模式打开,则此函数的返回值是未指定的,而且仅若作为 std::fseek 的输入才有意义。

参数

stream - 要检验的文件流

返回值

成功时为文件位置指示器,若失败出现则为 -1L 。失败时亦设置 errno 。

获取文件位置指示器

std::fgetpos

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

获得文件流 stream 的文件位置指示器和当前分析状态(若存在),并将它们存储于 pos 所指向的对象。存储的值仅在作为 std::fsetpos 的输入的情况有意义。

参数

stream - 要检验的文件流
pos - 指向要存储文件位置指示器到的 fpos_t 对象的指针

返回值

成功时为 ​0​ ,否则非零值。失败时还设置 errno 。

移动文件位置指示器到文件中的指定位置

std::fseek

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

设置文件流 stream 的文件位置指示器为 offset 所指向的值。

stream 以二进制模式打开,则新位置准确地是文件起始后(若 origin 为 SEEK_SET )或当前文件位置后(若 origin 为 SEEK_CUR ),或文件结尾后(若 origin 为 SEEK_END )的 offset 字节。不要求二进制流支持 SEEK_END ,尤其是是否输出附加的空字节。

stream 以文本模式打开,则仅有的受支持 offset 值为零(可用于任何 origin )和先前在关联到同一个文件的流上对 std::ftell 的调用的返回值(仅可用于 SEEK_SET 的 origin )。

stream 为宽面向,则一同应用对文本和二进制流的限制(允许 std::ftell 的结果与 SEEK_SET 一同使用,并允许零 offset 以 SEEK_SET 和 SEEK_CUR 但非 SEEK_END 为基准)。

除了更改文件位置指示器, fseek 还撤销 std::ungetc 的效果并清除文件尾状态,若可应用。

若发生读或写错误,则设置流的错误指示器( std::ferror )而不影响文件位置。

参数

stream - 要修改的文件流
offset - 相对 origin 迁移的字符数
origin - offset 所加上的位置。它能拥有下列值之一: SEEK_SET 、 SEEK_CUR 、 SEEK_END

返回值

成功时为 ​0​ ,否则为非零。

注意

在巡位到宽流的非结尾位置后,下个对任意输出函数的调用可能令剩下的文件内容未定义,例如通过输出一个长度不同的多字节序列。

对于文本流, offset 仅有的合法值是 ​0​ (可应用于任意 origin )和先前 ftell 调用的返回值(仅可应用于 SEEK_SET )。

POSIX 允许在文件尾之后巡位。若在此巡位后进行输出,则任何间隙中的读取将返回零字节。在文件系统支持的场合,这会创建一个稀疏文件

POSIX 亦要求 fseek 先进行 fflush ,若有任何未写入数据(但是否恢复迁移状态是实现定义的)。标准 C++ 文件流保证冲入并反迁移: std::basic_filebuf::seekoff 。

移动文件位置指示器到文件中的指定位置

std::fsetpos

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

按照 pos 所指向的值,设置 C 文件流 stream 的文件位置指示器和多字节分析状态(若存在)。

除了建立新的分析状态和位置,调用此函数还会撤销 std::ungetc 的效果,并若设置了文件尾状态则清除之。

若读或写失败,则设置流的错误指示器( std::ferror )。

参数

stream - 要修改的文件流
pos - 指向 fpos_t 对象的指针,该对象获得自对与同一文件关联的流上的 std::fgetpos 调用

返回值

成功时为 ​0​ ,否则为非零值。失败时还设置 errno 。

注意

在寻位到宽流的非结尾位置后,下个对任何输出函数的调用可能使剩下的文件内容未定义,例如通过输出不同长度的多字节序列。

移动文件位置指示器到文件起始

std::rewind

void rewind( std::FILE* stream );

移动文件位置指示器到给定文件流的起始。

函数等价于 std::fseek(stream, 0, SEEK_SET); ,除了它清除文件尾和错误指示器。

此函数丢弃任何来自先前对 ungetc 调用的效果。

参数

stream - 要修改的文件流

返回值

(无)

调用示例1

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

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


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

    std::fseek(fp, 0, SEEK_END); // 寻位到结尾
    std::size_t filesize = std::ftell(fp);

    std::fseek(fp, 0, SEEK_SET); // 寻位到起始
    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\n", filesize);
    return 0;
}

输出

调用示例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("\n%u\n", size);

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

 输出

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/132796180