我正在尝试读取一个文件,就像我在Linux中使用选项more
一样。我只想尝试more
几乎相同的实现。
我的问题是当我按顺序读取文件时:
aaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbb
.....................
ccccccccccccccccccccc
例如:我在txt.file
中有100个字符串,按照我向您展示的顺序排列。因此,每个字符串都不会超过控制台的水平大小,而是在ENTER
之后。
该计划非常出色。我的意思是,如果我的txt.file
信息没有完全显示,我只需按SPACE
,然后从文件中查看我的另一个信息屏幕。
但是如果我用一个长字符串放一个大文本,它只是完全读取一个文件并显示文件的结尾。 我做错了什么?我可能不考虑控制台的水平尺寸?但我认为,在这种情况下Linux会为我考虑..你可以帮助我吗?
我的论点是:./more 0 1.txt
./more
- make file,0
- 我正在使用此字符串,1.txt
- 文件名。
我的代码:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
int getch();
void printRecord(int& numStr,struct winsize w, std::vector<std::string>& lines);
int main(int argc, char *argv[]) {
struct winsize w;
char ch;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
std::ifstream readRecord;
std::vector<std::string> lines;
std::string str;
readRecord.open(argv[2]);
int numStr= atoi(argv[1]);
while (!readRecord.eof())
{
getline(readRecord, str);
str.size();
lines.push_back(str);
}
printRecord(numStr,w, lines);
ch=getch();
while(ch!='q'){
if (ch==32)
{
numStr--;
printRecord(numStr,w,lines);
}
if (numStr>=lines.size()){
break;}
ch=getch();
}
return 0;
}
void printRecord(int& numStr,struct winsize w,std::vector<std::string>& lines)
{
for (int i = numStr; i < numStr + w.winsize::ws_row-1; i++)
{
if (i>=lines.size())
break;
else
std::cout << lines[i] << std::endl;
}
numStr += w.winsize::ws_row;
}
int getch()
{
int ch;
struct termios oldt, newt;
tcgetattr( STDIN_FILENO, &oldt );
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
ch = getchar();
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return ch;
}
答案 0 :(得分:3)
不,Linux在这种情况下不会“为我考虑”。如果您的代码按原样打印出文件的内容,则文件的内容将打印到标准输出。如果终端不足以显示文件的内容,则只有屏幕上的任何内容都将保留在最后。在打印文件的内容时,文件的初始部分将在显示滚动之前短暂显示。
终端不会自动为您的程序输出分页。那是真正的more
工作。如果您想复制more
的功能,您必须自己完成。
您的程序可以通过制作您应该阅读的TIOCGWINSZ
ioctl,as explained in the tty_ioctl(4)
manual page来获取终端显示的大小。在获得终端的大小之后,您的程序将决定文件的内容在屏幕上的适合程度,并正确地对其进行分页。
如果您必须处理多字节UTF-8编码内容,那么事情变得非常复杂,如果您的输出包含某些亚洲字符集,更不用说双宽字符。在国际化和本地化时代,计算印刷文本的实际尺寸是非常困难的。但是,对于普通的拉丁文本,这应该足够了。您还应该为SIGWINCH
设置信号处理程序,如该手册页中所述,以检测对终端大小的更改,以便您可以相应地重新分隔文件的内容。
您还可以考虑使用更高级别的库,例如curses,在这种情况下可能会有用。