垂直遍历文件
Traverse file vertically
我需要以垂直方式遍历一个文件。如果假设文件内容为:
adg
beh
cfi
它应该将文件打印为:
abc
def
ghi
每条线的长度将是相同的(即,对于上述示例,所有线的长度都为3)。我已经写了一段代码,但它没有按要求遍历文件。
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
fstream fs;
fs.open("asd.txt",ios::in);
string str;
char *ch = new char();
int lineLen = 0, k = 0;
if(getline(fs,str))
{
lineLen = str.length();
}
fs.seekg(0);
if(lineLen > 0)
{
for(int i = 0;i<lineLen;i++)
{
fs.seekg(i+k*lineLen);
while(fs.read(ch,1))
{
k++;
fs.seekg(i+k*lineLen);
cout<<*ch;
}
k = 0;
}
}
fs.close();
cin.ignore();
}
我对文件处理有点陌生,找不到错误。此外,是否有更好的方法可供遵循?
在上做了一些小调整
//lines = no. of lines in file
fs.seekg(0, fs.beg);
fs.clear();
if(lineLen > 0)
{
for(int k = 0; k < lineLen; k++) {
for(int i = 0;i<lines;i++){
fs.seekg(k+i * (lineLen + 2), fs.beg); //use lines + 2
if(fs.read (ch,1));
cout << *ch;
}
cout << endl;
}
未测试的伪代码,可能会给您一些想法。基本上,将整个文件加载到一个二维字符向量中,以便访问。它将使用比直接从文件中读取更多的内存,但这并不重要,除非文件很大。
vector<vector<char>> filemap;
string line;
while (getline(filestream, line))
{
filemap.push_back(vector<char>(line.begin(), line.end()));
}
for (int x = 0; x < XSIZE; x++)
{
for (int y = 0; y < YSIZE; y++)
{
filestream << filemap[y][x]; // note x/y are opposite way round in 2d vectors
}
filestream << 'n';
}
如果使用mmap(2)
,您可能会发现此任务要简单得多。可能有一个C++等价物或包装器,但恐怕我不是这方面的专家。如果是这样的话,希望有人能给出一个更好的答案。
下面是一个快速的C(非++)示例。我会看看我是否可以在谷歌上搜索并用C++再验证一下:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
int fd = open("input", O_RDONLY);
struct stat s;
fstat(fd, &s);
// map the file as one big string
char *c = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
// calculate sizes
int columns = strchr(c, 'n') - c; // first newline delimits a row
int stride = columns + 1; // count the newline!
int rows = s.st_size / stride; // all rows are the same length
for (int x = 0; x < columns; x++)
{
for (int y = 0; y < rows; y++)
{
putchar(c[y*stride + x]);
}
putchar('n');
}
munmap(c, s.st_size);
close(fd);
return 0;
}
编辑:据我所知,在C++中快速搜索并没有找到更好的方法来处理这个问题。我的意思是,我可以在mmap
行上添加一个类型转换,并将putchar
调用更改为std::cout
,但这似乎并没有什么区别。
与其在源文件中重复查找(),不如简单地读取整个源文件,然后从内存中的内容生成输出。
这听起来很像课堂作业,所以我不会简单地为你写答案。然而,这应该会给你指明正确的方向——中包含一些PseodoCode
为了避免疼痛,假设线路长度和最大线路的上限是安全的,即
const int MaxLines = 100;
const int MaxLength = 80;
int lineno, linelength;
// array of char pointers for each line
char *lines[] = (*lines[])malloc(Maxlines * sizeof(char*));
// ReadLoop
lineno = 0;
while (not eof)
{
getline(buffer);
if (++lineno++ == 1)
{
linelength = strlen(buffer);
}
else
{
if (linelength != strlen(buffer))
{
cout "Line # " << lineno << " does not match the expected length";
exit();
}
}
lines[lineno] = malloc(strlen(buffer)+1));
strcpy(lines[lineno], buffer);
}
int cc, linecnt = lineno;
// now all data in memory, output "vertical data"
for (cc = 0; cc < linelength; ++cc)
{
for (lineno=0; lineno<<linelength; ++lineno)
{
cout << lines[xx][yy]; // xx && yy left you to figure out
}
cout "n";
}
如果您的文件不是很大,那么就没有理由不把整个文件拖到内存中。在C++中可能有一种更惯用的方法来实现这一点,但以下方法有效:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
int main(int argc, char *argv[])
{
std::fstream infile("foo.txt");
std::vector<std::string> lines;
std::string line;
while(std::getline(infile,line)) {
lines.push_back(line);
}
int m=lines.size();
int n=lines[0].length();
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
std::cout << lines[j].at(i);
}
std::cout << std::endl;
}
return 0;
}
当然,当文件中的所有行的长度都不相同时,就会出现问题。
现在,一个"不使用任何额外内存"的版本(当然,它使用了,但不多):
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
int main(int argc, char *argv[])
{
std::fstream infile("foo.txt");
std::vector<std::string> lines;
std::string line;
std::getline(infile, line);
int n = line.length();
int m = 1+std::count(std::istreambuf_iterator<char>(infile),
std::istreambuf_iterator<char>(), 'n');
infile.clear();
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
infile.seekg(j*m+i);
std::cout << char(infile.peek());
}
std::cout << std::endl;
}
return 0;
}
相关文章:
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 遍历顺序由 std::文件系统directory_iterator给出
- 如何遍历几个每小时一次的根(.root)文件,并将它们组合成更大的每日数据.root文件?
- 遍历对象向量,并找到与从文本文件中提取的对象匹配的变量
- 我该如何循环遍历我的数组(缓冲区——包含一个文本文件),并将其打印成30字节的块
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- 使用 stdin 读取文本文件,然后遍历多个数组
- 是否可以遍历文本文件行并使用字符串流来解析每一行
- clang ast访问者,避免遍历文件
- 遍历指定文件夹的目录?Qt 和 c++
- 遍历目录中两个文件对
- 在qt中遍历文件夹中的文件非常慢
- 如何使用QDirIterator只遍历特定类型的文件
- C++遍历目录中的文件并写入其他目录
- 如何遍历当前目录并将文件存储在数组中?Bash 外壳脚本
- 有没有办法以编程方式遍历头文件
- 遍历文件夹中的文件(C++)
- 垂直遍历文件
- 遍历文件时跳过最后K行
- istream_iterator,用于遍历二进制文件中的字节