将 tabify 应用于我的文本文件导致我的文件 reader 出现段错误

Applying tabify to my text file causes my file reader to seg fault

我有一个包含以下文本的文件 records.txt

John    Smith   Sales   555-1234

Mary    Jones   Wages   555-9876

Paul    Harris  Accts   555-4321

我已经将 Mike McGrath C++ 编程 中的以下代码复制到文件 format.cpp 中以读取 records.txt 中的数据:

#include <fstream>
#include <string>
#include <iostream>
using namespace std;

int main()
{
  const int RANGE = 12;
  string tab[RANGE];
  int i = 0, j = 0;
  ifstream reader("records.txt");
  if (!reader)
    {
      cout << "Error opening input file" << endl;
      return -1;
    }
  while (!reader.eof())
    {
      if ((i + 1) % 4 == 0)
        getline(reader, tab[i++], '\n');
      else
        getline(reader, tab[i++], '\t');
    }
  reader.close();
  i = 0;
  while (i < RANGE)
    {
      cout << endl << "Record Number: " << ++j << endl;
      cout << "Forename: " << tab[i++] << endl;
      cout << "Surname: " << tab[i++] << endl;
      cout << "Daprtment: " << tab[i++] << endl;
      cout << "Telephone: " << tab[i++] << endl;
    }
  return 0;
}

现在,在我的 .emacs 文件中,根据以下命令,我的所有文件中的制表符自动转换为空格:

(setq-default indent-tabs-mode nil)

所以当我编译 运行 format.out 时,我得到以下输出:

$ ./format.out 

Record Number: 1
Forename: John    Smith   Sales   555-1234
Mary    Jones   Wages   555-9876
Paul    Harris  Accts   555-4321

Surname: 
Daprtment: 
Telephone: 

Record Number: 2
Forename: 
Surname: 
Daprtment: 
Telephone: 

Record Number: 3
Forename: 
Surname: 
Daprtment: 
Telephone: 

这不是我想要的。我想要的是将每个制表符分隔的项目打印在其对应的标签之后。

所以我进入 emacs 并输入以下命令将空格转换为制表符 records.txt:

M-x tabify

但是现在当我重新运行我的脚本时,我遇到了段错误:

$ ./format.out 
Segmentation fault (core dumped)

为什么会这样,我该如何解决? (或者,如果原因不明显,我可以做些什么来进一步调查?)

我的 c++ 代码似乎有问题,而不是文件本身,因为当我阅读 python 中的 records.txt 时,我可以看到它符合预期:

In [1]: with open('records.txt') as f:
   ...:     x = f.readlines()
   ...:     

In [2]: x
Out[2]: 
['John\tSmith\tSales\t555-1234\n',
 'Mary\tJones\tWages\t555-9876\n',
 'Paul\tHarris\tAccts\t555-4321\n']

您可以先阅读为什么 while (!reader.eof()) 是错误的,Why is iostream::eof inside a loop condition considered wrong?。看来你抄代码的书不是很好

我想这是你的段错误的原因,因为不正确的 eof 检查你在你的循环中进行了太多次并且对你的数组进行了越界访问。您可以通过将数组的大小增加到 13 来检查这一点。

买一本更好的书(顺便问一下,那是什么书?)。

这是一种读取文件的可能方法(未经测试的代码)

for (;;)
{
    char delim;
    if ((i + 1) % 4 == 0)
        delim = '\n';
    else
        delim = '\t';
    if (!getline(reader, tab[i++], delim))
        break; // eof or some other error
}