2

我需要以垂直方式遍历文件。如果假设文件内容是:

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();
}

我对文件处理有点陌生,找不到错误。另外,有没有更好的方法可以遵循?

4

5 回答 5

2

几乎你的方式与一些小调整

//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;
}
于 2013-08-30T17:51:52.597 回答
1

如果您使用mmap(2). 可能有 C++ 等价物或包装器,但恐怕我不是这方面的专家。如果是这样的话,希望有人会提出更好的答案。

这是一个快速的 C(不是 ++)示例。我会看看我是否可以用谷歌搜索并 C++ify 更多:

#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更改为,但这似乎并没有什么区别。putcharstd::cout

于 2013-08-30T16:55:57.043 回答
1

未经测试的伪代码,可能会给你一些想法。基本上,将整个文件加载到 2d 字符向量中以便于访问。它会比直接从文件中读取更多的内存,但这并不重要,除非文件很大。

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';
}
于 2013-08-30T17:08:46.773 回答
1

与其在源文件中反复尝试 seek() ,不如简单地读取整个源文件然后从内存中的内容生成输出,这样更容易、更快捷。

这听起来很像课堂作业,所以我不会简单地为你写答案。但是,这应该为您指明正确的方向——包括一些 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";
}
于 2013-08-30T17:24:07.993 回答
0

如果您的文件不是很大,那么没有理由不将整个内容放入内存中。在 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;
}
于 2013-08-30T17:34:15.193 回答