我正在嘗試讀取包含段落的檔案,計算特定單詞出現的次數(我指定并存盤在陣列中的單詞),然后將該結果列印到另一個看起來像這樣的檔案,
systems, 2
computer, 3
programming, 6
等等。目前,這段代碼所做的只是吐出段落中的每個單詞及其各自的計數。任何幫助將非常感激。
#include <stdio.h>
#include <string.h>
int main()
{
FILE* in;
FILE* out;
char arr1[13][100] = { "systems", "programming", "computer", "applications", "language", "machine"};
int arr2[180] = {0};
int count = 0;
char temp[150];
in = fopen("out2.dat", "r");
out = fopen("out3.dat", "w");
while (fscanf(in, "%s", temp) != EOF)
{
int i, check = 8;
for (i = 0;i < count;i )
{
if (strcmp(temp, arr1[i]) == 0)
{
arr2[i] ;
check = 1;
break;
}
}
if (check == 1) continue;
strcpy(arr1[count], temp);
arr2[count ] = 1;
}
int i;
for (i = 0; i < count; i )
fprintf(out, "%s, %d\n", arr1[i], arr2[i]);
return 0;
}
uj5u.com熱心網友回復:
在整個程式中使用count沒有多大意義。
它被宣告為int count = 0;,然后在此回圈中用作上限
for (i = 0; i < count; i )
限制將使用哪些搜索詞。這也意味著這個回圈不會在周圍while回圈的第一次迭代中進入。
因此,check != 1, 所以在此之后count用作arr1當前讀取的“單詞”將被復制到的索引
strcpy(arr1[count], temp);
這完全沒有意義。為什么要覆寫您正在搜索的資料?
然后在用于設定 to 的第一個元素后count遞增to 。1arr21
在回圈的第二次迭代中while,for回圈將運行一次迭代,將新讀取的“單詞”(temp)與第一個元素arr1(現在是最后讀取的“單詞”)進行比較。
如果匹配: in 的第一個元素arr2從1to遞增2,則跳過字串副本,并且count不遞增。
如果不匹配,則將新的“單詞”復制到 的第二個元素中arr1,將 的第二個元素arr2設定為1,并count遞增為2。
這從這里開始失控。
給定上面顯示的輸入,當到達時this 訪問arr1越界。count13
對于具有少量資料選擇的檔案(<= 13 個唯一“單詞”,長度 < 100),這可能會通過填充arr1檔案中的單詞而意外“起作用”。這將具有向您顯示輸入檔案中每個“單詞”的計數的最終效果。
最終,當發生以下情況之一時,您將呼叫未定義行為:
fscanf(in, "%s", temp)讀取溢位temp緩沖區的字串。count超出arr1or的范圍arr2。strcpy(arr1[count], temp);復制一個溢位緩沖區的字串arr1。- 要么
fopen失敗。
除了不安全之外,fscanf(in, "%s", temp)還會將除空格之外的任何內容視為有效字串的一部分。這包括尾隨標點符號,這可能是也可能不是問題,具體取決于您要匹配的標記(systems.vs. systems)。您可能需要更健壯的決議。
在任何情況下,要么創建一個由搜索詞和頻率組成的結構陣列,要么創建兩個相同長度的陣列來表示此資料:
const char *words[6] = { "systems", "programming", "computer", "applications", "language", "machine"};
unsigned freq[6] = { 0 };
沒有必要復制任何東西。記得檢查是否fopen失敗,并限制%s讀取時不溢位輸入緩沖區。
程式的其余部分看起來相似:針對所有搜索詞測驗每個輸入“詞”;如果匹配,則增加相應的頻率。
使用結構陣列的示例:
#include <stdio.h>
#include <string.h>
int main(void) {
struct {
const char *word;
unsigned freq;
} search_words[] = {
{ "systems", 0 },
{ "programming", 0 },
{ "computer", 0 },
{ "applications", 0 },
{ "language", 0 },
{ "machine", 0 }
};
size_t length = sizeof search_words / sizeof *search_words;
FILE *input_file = fopen("out2.dat", "r");
FILE *output_file = fopen("out3.dat", "w");
if (!input_file || !output_file) {
fclose(input_file);
fclose(output_file);
fprintf(stderr, "Could not access files.\n");
return 1;
}
char word[256];
while (1 == fscanf(input_file, "%5s", word))
for (size_t i = 0; i < length; i )
if (0 == strcmp(word, search_words[i].word))
search_words[i].freq ;
fclose(input_file);
for (size_t i = 0; i < length; i )
fprintf(output_file, "%s, %u\n",
search_words[i].word,
search_words[i].freq);
fclose(output_file);
}
cat out3.dat:
systems, 1
programming, 1
computer, 2
applications, 2
language, 1
machine, 1
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/453334.html
