首页 > 解决方案 > 读取和打印最后 N 个字符

问题描述

我有一个程序,我想用它来读取文件并输出它的最后 N 个字符(可以是 50 或我编码的任何字符)。从我的一段代码中,我得到的输出是菱形框中的问号,(不支持的 unicode?)

我正在使用 lseek 设置光标,有人可以帮助我吗?

int main(int argc,char *argv[]){
    int fd; //file descriptor to hold open info
    int count=0; //to hold value of last 200th char number
    char ch; //holds read char
    char* outputString = "The file does not exist!\n";
    if(!access("myFile.txt",F_OK)==0){
        write(2,outputString,strlen(outputString));
        exit(1);
    }
    fd = open("myFile.txt",O_RDONLY| O_NONBLOCK);
    int ret = lseek(fd,200,SEEK_END); //get position of the last 200th item
    while (ret!=0) {
          write(1, &ch,1);
          ret--;
    }
    close(fd);
    return(0);
}

我不想使用<stdio.h>函数,所以我使用文件描述符而不是创建FILE*对象。

标签: file-descriptortaillseek

解决方案


我稍微修改了你的尝试。lseek(fd, 200, SEEK_END)查找文件末尾后 200 个字符文件。如果要从文件中读取最后 200 个字符,则需要查找到文件末尾的 200 个字符lseek(fd, -200, SEEK_END).

我在代码中添加了一些注释以帮助解释。

// please include headers when posting questions on stackoverflow
// It makes it way easier to reproduce and play with the code from others
#include <unistd.h>
#include <error.h>
// I use glibc error(3) to handle errors
#include <errno.h>
#include <stdlib.h> 
#include <fcntl.h>

int main(int argc,char *argv[]){
    // no idea if a typo, myFile.txt != logfile.txt
    if(!access("myFile.txt", F_OK) == 0) {
        error(1, errno, "The file does not exist!");
        exit(1);
    }

    int fd = open("logfile.txt", O_RDONLY | O_NONBLOCK);
    if (fd == -1) { 
        error(1, errno, "Failed opening the file");
    }

    // move cursor position to the 200th characters from the end
    int ret = lseek(fd, -200, SEEK_END); 
    if (ret == -1) {
        error(1, errno, "Failed seeking the file");
    }

    // we break below
    while (1) { 
          char ch = 0; // holds read char
          ssize_t readed = read(fd, &ch, sizeof(ch));
          if (readed == 0) { 
              // end-of-file, break
              break;
          } else if (readed == -1) {
              // error handle
              // actually we could handle `readed != 1`
              error(1, errno, "Error reading from file");
          }
          // output the readed character on stdout
          // note that `STDOUT_FILENO` as more readable alternative to plain `1`
          write(STDOUT_FILENO, &ch, sizeof(ch));
    }

    close(fd);

    return 0;
}

推荐阅读