在C ++中从文本文件中打印出空格

时间:2013-10-24 03:25:30

标签: c++ vector

#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <string>
#include <iomanip>
#include <fstream>
#include <stdio.h>
using namespace std;

int main()
{
    ifstream file;
    string filename;
    char character;
    int letters[153] = {};

    cout << "Enter text file name: ";
    cin >> filename;    
    file.open(filename.c_str());
    if (! file.is_open())
    {
        cout << "Error opening file. Check file name. Exiting program." << endl;
        exit(0);
    }

    while (file.peek() != EOF)
    {
        file >> character;
        if(!file.fail())
        {
            letters[static_cast<int>(character)]++;
        }
    }

    for (int i = 0; i <= 153; i++)
    {
        if (letters[i] > 0)
        {
            cout << static_cast<char>(i) << " " << letters[i] << endl;
        }
    }

    exit(0);
}

#endif

大家好,我当前的代码计算文本文件中每个字母的频率。但是,它不计算空格的数量。有没有一种简单的方法可以打印出.txt文件中的空格数?

另外,为什么当我尝试访问矢量项时,我遇到了一个段错误? 例如,如果我使用:

cout&lt;&lt; “”+字母[i]&lt;&lt; endl;,它显示一个段错误。有什么想法吗?

非常感谢你。

2 个答案:

答案 0 :(得分:2)

默认情况下,iostreams格式化的输入提取操作(使用>>的操作)跳过所有空格字符以获取第一个非空白字符。也许令人惊讶的是,这包括char的提取运算符。为了将空格字符视为要照常处理的字符,您应该在处理之前更改noskipws manipulator

file << std::noskipws;

不要忘记稍后再重新设置:

file << std::skipws;

如果你是那些疯狂的人之一想要在退出之前创建一个离开流状态的这个方面(或者甚至是所有方面) 的人?当然,C ++提供了一种令人沮丧的丑陋方式来实现这一目标:

std::ios_base::fmtflags old_fmt = file.flags();
file << std::noskipws;

...  // Do your thang

file.flags(old_fmt);

答案 1 :(得分:1)

我只是将此作为替代方式来做你正在尝试的事情。这使用了您在代码中使用的相同查找表方法,但使用istreambuf_iterator直接从流缓冲区中清除未格式化(和未过滤)的原始字符。

#include <iostream>
#include <fstream>
#include <iterator>
#include <climits>

int main(int argc, char *argv[])
{
    if (argc < 2)
        return EXIT_FAILURE;

    std::ifstream inf(argv[1]);
    std::istreambuf_iterator<char> it_inf(inf), it_eof;

    unsigned int arr[1 << CHAR_BIT] = {};
    std::for_each(it_inf, it_eof,
         [&arr](char c){ ++arr[static_cast<unsigned int>(c)];});

    for (int i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
    {
        if (std::isprint(i) && arr[i])
            std::cout << static_cast<char>(i) << ':' << arr[i] << std::endl;
    }

    return 0;
}

在源代码文件本身上执行此操作(即上面的代码)会生成以下内容:

 :124
#:4
&:3
':2
(:13
):13
*:1
+:4
,:4
/:1
0:3
1:2
2:1
::13
;:10
<:19
=:2
>:7
A:2
B:1
C:1
E:2
F:1
H:1
I:3
L:1
R:2
T:2
U:1
X:1
[:8
]:8
_:10
a:27
b:1
c:19
d:13
e:20
f:15
g:6
h:5
i:42
l:6
m:6
n:22
o:10
p:1
r:37
s:20
t:34
u:10
v:2
z:2
{:4
}:4

只是采用不同的方式,但很明显,通常C ++标准库提供了优雅的方法来做你想要的东西,如果你深入挖掘到那里找到什么。祝你好运。