我想从显示最常或最不常出现的字符的文本文件中读取(键盘或文本文件)? :)

时间:2017-11-13 03:40:20

标签: c

这是我的代码:

include <stdio.h>

int main()
{
   char str[1000], ch;
   int i, frequency = 0;

   printf("Enter a string: ");
   gets(str);

   printf("Enter a character to find the frequency: ");
   scanf("%c",&ch);

   for(i = 0; str[i] != '\0'; ++i)
   {
       if(ch == str[i])
           ++frequency;
   }

   printf("Frequency of %c = %d", ch, frequency);

   return 0;

我认为我提出的字符代码的频率是相似的。如何在标准输入或文本文件中实现更多/更少出现的字符?

另外,我应该使用StreamReader sr = new StreamReader("example.txt")来读取此代码的普通文本文件吗?

编辑:最常使用Switch / M和/ L最少使用。

2 个答案:

答案 0 :(得分:0)

这是一个好的开始......

include <stdio.h>

int main()
{
   char str[1000], ch,lookup_Chars[256];
   int i, frequency = 0;
   char counter;
   printf("Enter a string: ");
   gets(str);

   printf("Enter a character to find the frequency: ");
   scanf("%c",&ch);

   for(i = 0; str[i] != '\0'; ++i)
   {
       lookup_Chars[str[i]]++;
   }
  for(counter = 0; counter<sizeof(lookup_Chars); counter++)
   {
        printf("Frequency of %c = %d", counter, lookup_Chars[counter]);
   }


   return 0;

答案 1 :(得分:0)

永远不要永远不要使用gets。它是如此不安全并且容易受到缓冲区溢出的影响,它已从C标准库中删除。请改用fgets,只需注意fgets将读取并在其填充的缓冲区中包含尾随'\n'(就像所有合法的面向行的输入函数一样) ,例如POSIX getline)。这可以防止在每次用户输入后在输入缓冲区(例如'\n')中留下stdin未读。

您冒着未定义的行为的风险,因为您没有以任何方式验证 {/ 1}}的内容,然后您无法验证返回str确保角色被阅读。 (用户可以通过在windoze上使用 Ctrl + z 的* nix系统上使用 Ctrl + d 生成scanf来取消输入。

此外,您必须了解EOF将在输入缓冲区中留下字符(如果该行长于您已分配的存储量,则会scanf)。这是新C程序员成为受害者最常见的陷阱之一。 (未能验证完整的输入行被读取并且无法处理保留在输入缓冲区中的字符)

当使用fgets(建议使用)进行用户输入时,由于它读取并包含填充的缓冲区中的“fgets,因此您只需使用{{1”检查读取的缓冲区的长度然后确保最后一个字符是\n'

当用于用户输入时,

strlen充满了陷阱。虽然可以使用它,如果正确使用它的返回验证,并且在下次调用'\n'之前从scanf清空任何剩余的字符,则必须以这种方式使用它。在您的情况下,stdin是您文件的最后一个输入,但在阅读字符串之前尝试获取scanf的输入,看看会发生什么......

完全放置,并为chch添加验证,并在下面添加其他评论,您可以执行类似以下操作:

str

注意>您可以声明ch并使用#include <stdio.h> #include <string.h> #define MAXS 1024 /* if you need a constant, define one */ int main (void) { int frequency = 0; char str[MAXS] = "", *p = str, /* pointer to str */ ch; printf ("Enter a string: "); if (fgets (str, MAXS, stdin)) { /* validate input received */ size_t len = strlen (str); /* get length of str */ if (len && str[len - 1] != '\n') { /* validate all input read */ fprintf (stderr, "error: line exceeds %d chars.\n", MAXS-2); return 1; } } else { /* if fgets failed - user generated EOF to cancel */ fprintf (stderr, "error: user canceled input (EOF).\n"); return 1; } printf ("Enter a character to find the frequency: "); if (scanf ("%c", &ch) != 1) { /* note: chars will remain in stdin */ fprintf (stderr, "error: user canceled input.\n"); return 1; } while (*p != '\n') /* just use a pointer to str */ if (*p++ == ch) /* compare to ch and increment to next char */ frequency++; /* increment frequency if they are equal */ printf ("\nFrequency of %c = %d\n", ch, frequency); return 0; } 阅读char ch[3] = "";,然后只需比较fgets以防止离开'fgets (ch, sizeof ch, stdin)if (*p++ == *ch)中{1}}(但您仍需要验证它是最后一个字符读取,如果不是手动清空\n'))

检查使用/输出

stdin

仔细看看,考虑所做的验证,如果您有任何其他问题,请告诉我。

使用频率阵列捕获所有字符的数量

使用频率数组可以捕获所有字符的频率(或集合中任何元素的独立计数)。基本上,您使用一个数组初始化为零,每个成员的一个元素要计算每次出现的频率。由于有stdin ASCII Characters,您只需使用$ ./bin/freqofc Enter a string: a man a plan a canal panama Enter a character to find the frequency: a Frequency of a = 10 $ ./bin/freqofc Enter a string: a man a plan a canal panama Enter a character to find the frequency: p Frequency of p = 2 $ ./bin/freqofc Enter a string: a man a plan a canal panama Enter a character to find the frequency: z Frequency of z = 0 元素数组,例如128

如果查看提供的链接,您会看到每个字符的ASCII值对应于128之间的值,因此当循环输入字符串中的每个字符时,如果增加对应的数组索引在该字符中,您最终得到其相应元素中每个字符的总计数。例如,如果int frequency[128] = {0};是指向0-127开头的指针,那么您可以遍历字符串中的每个字符,捕获它们在数组的p元素中的频率:

str

现在您拥有frequency[*p]中存储的每个字符的频率,您可以简单地遍历您关注的元素以确定while (*p != '\n') { frequency[*p]++; /* increments element corresponding to char *p */ p++; /* note: cast to (int)*p intentional omitted */ } 等... 注意: 正常的可打印字符以frequency(ASCII max/min或十六进制'space')开头,以32结尾(ASCII {{1 }或十六进制0x7e`)。因此,只需将值检查限制在可打印范围内,例如

0x20

注意:您可以进一步对小写,大写,数字等进行微分范围。)

总而言之,你可以做类似以下的事情来报告发生的次数,如果想要的字符,最大出现的字符,最小出现的字符(然后通过倾倒所有字符的频率汇总):

'~'

检查使用/输出

126

添加/ L或/ M切换最少/最大次数

要添加命令行开关,对于已知顺序中的最小数字,您只需使用允许的参数计数参数向量参数 /* loop over printable characters (see ASCII Chart), for max/min */ for (int i = ' '; i <= '~'; i++) { /* require a frequency of at least 1 for min */ if (frequency[i] && frequency[i] < min) { min = frequency[i]; /* save least frequent count */ minc = i; /* save least frequent char */ } if (frequency[i] > max) { /* just find max */ max = frequency[i]; /* save same for max */ maxc = i; } } ,例如#include <stdio.h> #include <string.h> #include <limits.h> #define MAXS 1024 /* if you need a constant, define one */ #define NASCII 128 /* number of ASCII chars (includes non-printing) */ int main (void) { int frequency[NASCII] = {0}, max = INT_MIN, min = INT_MAX; char str[MAXS] = "", *p = str, /* pointer to str */ ch, minc = 0, maxc = 0; printf ("Enter a string: "); if (fgets (str, MAXS, stdin)) { /* validate input received */ size_t len = strlen (str); /* get length of str */ if (len && str[len - 1] != '\n') { /* validate all input read */ fprintf (stderr, "error: line exceeds %d chars.\n", MAXS-2); return 1; } } else { /* if fgets failed - user generated EOF to cancel */ fprintf (stderr, "error: user canceled input (EOF).\n"); return 1; } printf ("Enter a character to find the frequency: "); if (scanf ("%c", &ch) != 1) { /* note: chars will remain in stdin */ fprintf (stderr, "error: user canceled input.\n"); return 1; } while (*p != '\n') /* just use a pointer to str */ frequency[(int)*p++]++; /* increment element representing ch */ /* loop over printable characters (see ASCII Chart), for max/min */ for (int i = ' '; i <= '~'; i++) { /* require a frequency of at least 1 for min */ if (frequency[i] && frequency[i] < min) { min = frequency[i]; /* save least frequent count */ minc = i; /* save least frequent char */ } if (frequency[i] > max) { /* just find max */ max = frequency[i]; /* save same for max */ maxc = i; } } /* ouput requested char freq, and max/min chars */ printf ("\nFrequency of %c = %d\n" "least frequent occurrence: %c = %d\n" " most frequent occurrence: %c = %d\n\n", ch, frequency[(int)ch], minc, min, maxc, max); /* output frequency of all printable chars */ printf ("frequency of all printable characters:\n"); for (int i = ' '; i < '~'; i++) if (frequency[i]) printf (" '%c' : %d\n", i, frequency[i]); return 0; } 。例如:

$ ./bin/freqofc2
Enter a string: a man a plan a canal panama
Enter a character to find the frequency: m

Frequency of m = 2
least frequent occurrence: c = 1
 most frequent occurrence: a = 10

frequency of all printable characters:
  ' '  :  6
  'a'  :  10
  'c'  :  1
  'l'  :  2
  'm'  :  2
  'n'  :  4
  'p'  :  2

要测试和输出最小值或最小值,您只需测试存在哪个字符并采取相应措施,例如

main()

将它们放在一起就是一个完整的例子:

int main (int argc, char **argv)

如果您有任何问题,请与我们联系。