Use fseek()
with offset -1
and mode SEEK_END
:
fseek(myfile, -1, SEEK_END);
Ready-to-use function
#include <cstdio> #include <optional> /** * Read the last byte of a given */ std::optional<char> readLastByteOfFile(const char* filename) { FILE* fin = fopen(filename, "r"); if(fin == nullptr) { return std::nullopt; } fseek(fin, -1, SEEK_END); char lastByte; if(fread(&lastByte, 1, 1, fin) == 0) { return std::nullopt; } fclose(fin); return lastByte; }
Complete example program
#include <cstdlib> #include <cstdio> #include <iostream> #include <optional> /** * Read the last byte of a given */ std::optional<char> readLastByteOfFile(const char* filename) { FILE* fin = fopen(filename, "r"); if(fin == nullptr) { return std::nullopt; } fseek(fin, -1, SEEK_END); char lastByte; if(fread(&lastByte, 1, 1, fin) == 0) { return std::nullopt; } fclose(fin); return lastByte; } int main(int argc, char** argv) { if(argc < 2) { std::cerr << "Usage: " << argv[0] << " <input file to read from>" << std::endl; } auto lastByte = readLastByteOfFile(argv[1]); if(lastByte) { std::cout << lastByte.value() << std::endl; } else { std::cout << "File error or empty" << std::endl; } }
Generate test data with:
echo -n "abcd" > test.txt touch test2.txt
Compile using:
g++ -o read-last-byte read-last-byte.cpp --std=c++17
Test using:
$ ./test-last-byte test1.txt d $ ./test-last-byte test2.txt File error or no last byte