所以我用 C 語言撰寫了一個代碼來列印一個名為“harrypotter1.txt”的檔案(整個第一本哈利波特書)中每個字符的頻率。當它應該只列印檔案中的字符時,它的作業原理是在它旁邊列印帶有“:0”的隨機空格。下面我將列出我的代碼,并將它列印到螢屏上的輸出顯示,如果有人可以幫助我解決問題。注意:我需要使用結構!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
struct pair //struct to store frequency and value
{
int frequency;
char value;
};
int main()
{
struct pair table[128]; //set to 128 because these are the main characters
int fd; // file descriptor for opening file
char buffer[1]; // buffer for reading through files bytes
fd = open("harrypotter1.txt", O_RDONLY); // open a file in read mode
for(int j = 0; j < 128; j )//for loop to initialize the array of pair (struct)
{
table[j].value = j; // table with index j sets the struct char value to equal the index
table[j].frequency = 0; // then the table will initialize the frequency to be 0
}
while((read(fd, buffer, 1)) > 0) // read each character and count frequency
{
int k = buffer[0]; //index k is equal to buffer[0] with integer mask becasue each letter has a ASCII number.
table[k].frequency ; //using the struct pair table with index k to count the frequency of each character in text file
}
close(fd); // close the file
for (int i = 0; i < 128; i ) // use for loop to print frequency of characters
{
printf("%c: %d\n",table[i].value, table[i].frequency); // print characters and its frequency
}
return 0; //end of code
}
輸出:
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 3
: 10702
: 0
: 0
: 10702
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
: 0
0
: 0
: 0
: 0
: 0
: 70803
!: 474
": 4758
#: 0
$: 0
%: 0
&: 0
': 3141
(: 30
): 33
*: 2
: 0
,: 5658
-: 1990
.: 6136
/: 0
0: 5
1: 11
2: 3
3: 8
4: 6
5: 2
6: 1
7: 4
8: 1
9: 4
:: 69
;: 135
<: 0
=: 0
>: 0
?: 754
@: 0
A: 703
B: 348
C: 293
D: 685
E: 287
F: 426
G: 492
H: 2996
I: 1393
J: 51
K: 79
L: 209
M: 665
N: 488
O: 332
P: 639
Q: 203
R: 660
S: 844
T: 1055
U: 193
V: 192
W: 653
X: 2
Y: 326
Z: 5
[: 0
\: 1
]: 0
^: 0
_: 0
`: 0
a: 25887
b: 4980
c: 6403
d: 15932
e: 39628
f: 6431
g: 8127
h: 19535
i: 19422
j: 319
k: 3930
l: 14385
m: 6729
n: 21337
o: 25809
p: 4909
q: 217
r: 20990
s: 18870
t: 27993
u: 9562
v: 2716
w: 7744
x: 381
y: 8293
z: 259
{: 0
|: 0
}: 0
~: 1
: 0
*/
uj5u.com熱心網友回復:
Allan Wind 的 C 答案很好,因為它產生了正確的結果,但它確實分配了比解決問題所需的最小值更大的字符陣列。這種空間浪費是由于 C 陣列索引必須從 0 開始并且第一個可列印字符 ' ' 的值為 32 而最后一個可列印字符 '~' 的值為 126 的事實所強制的妥協。
with Ada.Text_IO; use Ada.Text_IO;
procedure count_graphic_characters is
subtype graphix is Character range ' ' .. '~';
counts : array (graphix) of Natural := (Others => 0);
The_file : File_Type;
C : Character;
begin
Open
(File => The_file, Mode => In_File,
Name => "src\count_graphic_characters.adb");
while not End_Of_File (The_file) loop
Get (File => The_file, Item => C);
counts (C) := counts (C) 1;
end loop;
Close (The_file);
for I in counts'Range loop
Put_Line (I & ": " & counts (I)'Image);
end loop;
end count_graphic_characters;
該程式使用 Ada 編程語言計算其自己的源檔案中字符的頻率。
子型別 graphix 被定義為包含所有從 ' ' 開始并以 '~' 結束的圖形字符。陣列名稱 counts 由子型別 graphix 中的字符索引。陣列的每個元素都是預定義子型別 Natural 的一個實體,并被初始化為 0。陣列包含的元素恰好足以計算源檔案中的每個圖形字符。
如果找不到在 Open 程序中命名的檔案,程式將引發例外。
當從檔案中讀取每個字符時,該字符將用作計數陣列的索引,并且相應的元素會遞增。
創建 128 個元素的陣列不會浪費空間。而是使用 95 個字符的陣列。也不需要檢查每個陣列元素來確定索引表示的字符是否是可列印字符,因為陣列索引值只是可列印字符。
這個程式的輸出是:
: 132
!: 0
": 4
#: 0
$: 0
%: 0
&: 2
': 6
(: 10
): 10
*: 0
: 1
,: 3
-: 0
.: 5
/: 0
0: 1
1: 1
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0
:: 6
;: 14
<: 0
=: 8
>: 6
?: 0
@: 0
A: 2
B: 0
C: 7
D: 0
E: 1
F: 5
G: 1
H: 0
I: 8
J: 0
K: 0
L: 1
M: 1
N: 2
O: 5
P: 1
Q: 0
R: 1
S: 0
T: 8
U: 0
V: 0
W: 0
X: 0
Y: 0
Z: 0
[: 0
\: 1
]: 0
^: 0
_: 18
`: 0
a: 26
b: 3
c: 21
d: 9
e: 43
f: 8
g: 9
h: 18
i: 22
j: 0
k: 0
l: 17
m: 3
n: 20
o: 22
p: 13
q: 0
r: 24
s: 15
t: 23
u: 13
v: 0
w: 2
x: 4
y: 3
z: 0
{: 0
|: 0
}: 0
~: 1
uj5u.com熱心網友回復:
您可以使用陣列而不是結構,因為值只是陣列索引:table[j].value = j;。初始化陣列,而不是在回圈中分配初始值。添加了打開的錯誤檢查。用于isprint()確定我們是否應該列印給定的字符:
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
// assumes 2^i to make the bitwise & work below
#define LEN 128
int main() {
unsigned frequency[LEN] = { 0 };
int fd = open("harrypotter1.txt", O_RDONLY);
if(fd == -1) {
printf("%s\n", strerror(errno));
return 1;
}
unsigned char buffer;
while((read(fd, &buffer, 1)) > 0) {
frequency[buffer & (LEN-1)] ;
}
close(fd);
for (int i = 0; i < LEN; i ) {
if(isprint(i))
printf("%c: %u\n", i, frequency[i]);
}
return 0;
}
并使用在輸入檔案中放置內容“hello world”,我得到以下輸出:
: 1
!: 0
": 0
#: 0
$: 0
%: 0
&: 0
': 0
(: 0
): 0
*: 0
: 0
,: 0
-: 0
.: 0
/: 0
0: 0
1: 0
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0
:: 0
;: 0
<: 0
=: 0
>: 0
?: 0
@: 0
A: 0
B: 0
C: 0
D: 0
E: 0
F: 0
G: 0
H: 0
I: 0
J: 0
K: 0
L: 0
M: 0
N: 0
O: 0
P: 0
Q: 0
R: 0
S: 0
T: 0
U: 0
V: 0
W: 0
X: 0
Y: 0
Z: 0
[: 0
\: 0
]: 0
^: 0
_: 0
`: 0
a: 0
b: 0
c: 0
d: 1
e: 1
f: 0
g: 0
h: 1
i: 0
j: 0
k: 0
l: 3
m: 0
n: 0
o: 2
p: 0
q: 0
r: 1
s: 0
t: 0
u: 0
v: 0
w: 1
x: 0
y: 0
z: 0
{: 0
|: 0
}: 0
~: 0
uj5u.com熱心網友回復:
前 32 個 ASCII 字符(值 0 - 31)是“不可列印的”,因為它們代表具有特殊含義或行為的字符。您可以按原樣保留代碼,但將實際列印輸出限制為僅包含“可列印”字符。您可以從空格' '(值 32)開始并在'z'(122) 結束,這將提供大部分可列印檔案(盡管不僅僅是字母)。
for (int i = ' '; i <= 'z'; i ) // use for loop to print frequency of characters
{
printf("%c: %d\n",table[i].value, table[i].frequency); // print characters and its frequency
}
從您的列印輸出中可以看到 10702 CR(值 13)和 10702 LF(值 10)表明該文本檔案有 10702 個換行符并且是一個 Windows 文本檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/464189.html
標籤:C
上一篇:通過兩通匯編器之一
