将 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
}
我有一个包含以下文本的文件 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
}