[英]Unexpected result while counting letters in file
因此,当遇到异常行为时,我正在编写一个 static 密码分析程序。
首先,我写了字符计数器,这就是问题出现的地方。
我有文件:
//alphabet.txt
abcdefghijklmnopqrstuvwxyz
当我尝试计算字母频率时,得到了一些有趣的结果,(不要注意第一行,它只是说 ifstream 是打开的)
D:\Workspaces\EclipseWS\StaticAnalysis\src>g++ main.cpp
D:\Workspaces\EclipseWS\StaticAnalysis\src>a.exe
1!
a 1
b 1
c 1
d 1
e 1
f 1
g 1
h 1
i 1
j 1
k 1
l 1
m 1
n 1
o 1
p 1
q 1
r 1
s 1
t 1
u 1
v 1
w 1
x 1
y 1
z 2
如您所见,程序说“z”在文本中出现了 2 次,但事实并非如此。
现在,技术细节。
Operating System: Windows 10 Enterprise LTSC
System Type: 64bit
C++ compiler: MinGW
alphabet.txt File encoding: ANSI
代码,我解析了文件:
#include <fstream>
#include <iostream>
#include <map>
#include <string>
using namespace std;
#define encrypted_fname "D:\\Workspaces\\EclipseWS\\StaticAnalysis\\src\\alphabet.txt"
void printMap(const map<char,int>& m){
for (const auto& p : m){
cout<<p.first<<'\t'<<p.second<<endl;
}
}
int main(){
ifstream ifs(encrypted_fname);
cout << ifs.is_open() << "!\n";
map<char,int> letterCount;
char buffer;
while(ifs){
ifs >> buffer;
letterCount[buffer]+=1;
}
printMap(letterCount);
}
我试图将文件编码更改为 UTF-8
1!
» 1
¿ 1
ï 1
a 1
b 1
c 1
d 1
e 1
f 1
g 1
h 1
i 1
j 1
k 1
l 1
m 1
n 1
o 1
p 1
q 1
r 1
s 1
t 1
u 1
v 1
w 1
x 1
y 1
z 2
..Unicode 大端\unicode ..
1!
þ 1
ÿ 1
28
a 1
b 1
c 1
d 1
e 1
f 1
g 1
h 1
i 1
j 1
k 1
l 1
m 1
n 1
o 1
p 1
q 1
r 1
s 1
t 1
u 1
v 1
w 1
x 1
y 1
z 1
但正如您所见,output 在任何情况下都有些蹩脚!
如果您需要,我可以提供更多信息,请告诉我如何获取它。
我的主要问题是:为什么会这样? 我的代码有错误吗? 如何解决?
while (1) {
ifs >> buffer;
if (! ifs) break;
letterCount[buffer]+=1;
} ;
应该这样做。 如果最后一次读取成功,“ifs”不会为假,只有当试图读取超出其末尾时,才会被评估为“假”。 但此时,作为最后一个字母的“z”不会被任何东西覆盖,并且会被计算两次。
这种用于读取文件的语法是在创建它时尝试为文本读取提供一个“漂亮的界面”。 我想说它不能打败用文件调用read(ifs, &buffer, 1)
。
您的其他奇怪结果是因为您总是从文件中读取字节,并且从不尝试将这些字节解码为文本 - 所以 BOM 标记和额外的 2 字节编码字节都被称为“unicode big endian”(正确的名称将是“utf-16 big endian”)将其所有字节视为字符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.