[英]c program to read file and count words specified in array
我正在嘗試讀取一個包含段落的文件,計算特定單詞出現的次數(我指定並存儲在數組中的單詞),然后將該結果打印到另一個看起來像的文件,
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;
}
在整個程序中使用count
沒有多大意義。
它被聲明為int count = 0;
, 然后用作此循環的上限
for (i = 0; i < count; i++)
限制將使用哪些搜索詞。 這也意味着該循環不會在周圍while
循環的第一次迭代時進入。
因此, check != 1
,因此在將此count
用作arr1
中的索引之后,當前讀取的“單詞”將被復制到
strcpy(arr1[count], temp);
這完全沒有意義。 為什么要覆蓋您正在搜索的數據?
然后count
在用於將arr2
的第一個元素設置為1
后遞增到1
。
在while
循環的第二次迭代中, for
循環將運行一次迭代,將新讀取的“單詞”( temp
) 與arr1
的第一個元素(現在是最后讀取的“單詞”)進行比較。
如果匹配: arr2
中的第一個元素從1
遞增到2
,則跳過字符串復制,並且count
不遞增。
如果這不匹配,則將新的“單詞”復制到arr1
的第二個元素,將arr2
的第二個元素設置為1
,並將count
遞增到2
。
這從這里開始失控。
鑒於上面顯示的輸入,當count
達到13
時,這將越界訪問arr1
。
對於具有少量數據選擇的文件(<= 13 個唯一“單詞”,長度 < 100),這可能會意外地“起作用”,方法是用文件中的單詞填充arr1
。 這將具有向您顯示輸入文件中每個“單詞”的計數的最終效果。
最終,當發生以下情況之一時,您將調用未定義的行為:
fscanf(in, "%s", temp)
讀取溢出temp
緩沖區的字符串。count
超出了arr1
或arr2
的范圍。strcpy(arr1[count], temp);
復制溢出arr1
緩沖區的字符串。fopen
失敗。 除了不安全之外, fscanf(in, "%s", temp)
會將空格以外的任何內容視為有效字符串的一部分。 這包括尾隨標點符號,這可能是也可能不是問題,具體取決於您要匹配的標記( systems.
與systems
)。 您可能需要更強大的解析。
在任何情況下,要么創建一個由搜索詞和頻率組成的結構數組,要么創建兩個相同長度的 arrays 來表示此數據:
const char *words[6] = { "systems", "programming", "computer", "applications", "language", "machine"};
unsigned freq[6] = { 0 };
無需復制任何內容。 請記住檢查fopen
是否失敗,並在讀取時限制%s
以免溢出輸入緩沖區。
該程序的 rest 看起來很相似:針對所有搜索詞測試每個輸入“詞”; 如果匹配則增加相應的頻率。
使用結構數組的示例:
#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, "%255s", 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.