【问题标题】:Setting number of looping设置循环次数
【发布时间】:2016-11-16 11:23:56
【问题描述】:

我有问题。我需要 tool.c 文件中的函数来仅循环所需的次数。就像它在循环整个输入后停止一样。我的老师说我应该通过第二个参数,但是下课了,我不知道它应该是什么样子。

ma​​in.c

#include <stdio.h>
#include <stdlib.h>
#include "tools.h"

int main(int argc, char *argv[]) {
    int count[256] = { 0 };
    int c;
    while ( (c=getchar())!=EOF ){
        count[c]++;
    }
    switch (argc > 1 && argv[1][1]) {
    case 'm': case 'M':
        mostOften(count);
        break;
    case 'l': case 'L':
        leastOften(count);
        break;
    default:
        mostOften(count);
        break;
    }
    return 0;
}

tools.c

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "tools.h"

void mostOften(int *s) {
    int j, a = 0;
    int max=0, cha;
    for(j=32; j<126; j++){
        if(s[j]>max) {
                max=s[j];
                cha=j;
        }
    a++;
    }
    printf("char %c: %d times\n", cha, max);
}

void leastOften(int *s) {
    int j, a = 0;
    int min=INT_MAX, cha;
    for(j=32; j<126; j++){
        if(s[j] && s[j]<=min) {
                min=s[j];
                cha=j;
        }
    a++;
    }
    printf("char %c: %d times\n", cha, min);
}

例如如果我输入

段落

我希望它只循环9次,基本上我需要设置一些if语句来停止循环

【问题讨论】:

  • 请将case 'm': case 'M': 分开放置。
  • switch (argc &gt; 1 &amp;&amp; argv[1][1]) { 应该是if(argc &gt; 1) switch (argv[1][1]) {
  • 请编辑您的问题并向我们展示输入和预期输出的示例。
  • @MichaelWalz 也许是这样的。
  • @zimek-atomek 你期望什么输出?

标签: c loops for-loop


【解决方案1】:

从您如何设置问题来看,您似乎在对作为输入的一部分的字符以及保存读取字符频率的数组进行迭代时感到困惑。

首先,为了让您的代码可读,不要在代码中使用幻数,例如32126。而是使用您尝试表示的字符,例如(<em>空格</em>)和~波浪号)。例如,不要使用:

for(j=32; j<126; j++){

你可以使用:

for(j = ' '; j < '~'; j++){

这也有它的陷阱。为什么?您不想遍历字符,您实际上想要遍历 count 数组中的元素,这些元素保存每个字符在输入中出现的频率。换句话说,您需要一个至少保存95 整数的数组,该数组将保存输入中每个字符出现的频率。既然你知道会有多少字符,就不要把它隐藏在32126 后面,只需在tools.h 中为你的数组大小声明一个常量(可能称为ARSZ),例如

#define ARSZ 95

然后在读取您的输入并填充count 数组后,只需遍历count 数组一次即可获得mostoftenleastoften 数字。此外,由于count 中的元素数量有一个常数,因此您不需要将count 的大小传递给mostoftenleastoften——您已经知道有多少元素存在,95 . (有关仅对输入中存在的字符进行迭代的说明,请参见下文)

(如果数组大小不是恒定的(并且您没有传递带有标记的数组,例如 nul-terminated 字符串)或者您需要迭代的元素数量未知编译时,那么您确实需要将数组的大小传递给函数。

(顺便说一句,C 通常对变量名使用全部小写,为常量和宏保留全部大写。您通常不会看到 MixedCasecamelCase em> C 中的变量名,留给 C++)

接下来,虽然您应该使用getopt 来处理命令行参数,但您可以使用快速技巧来检查有争议的参数的第二个字符,但您需要验证您至少有一个参数要检查并且参数不是 空字符串。基本上,您要检查:

if (argc > 1 && *argv[1])  /* check argc & not empty-string */
    switch (argv[1][1]) {
        case 'm':
            mostoften (count);
            break;
        case 'M':
            mostoften (count);
            break;
        case 'l':
            leastoften (count);
            break;
        case 'L':
            leastoften (count);
            break;
        default:
            fprintf (stderr, "warning: unrecognized option, using 'mostoften'.\n");
            mostoften (count);
    }
else {
    fprintf (stderr, "warning: no option given using 'mostoften'.\n");
    mostoften (count);
}

注意:对于switch 的任何单个情况,您不能将两个常量条件放在一起(某些编译器提供非标准扩展)。另请注意,在 default 的情况下,您不需要 break,因为不可能发生故障。

总而言之,您可以将tools.h 写成类似于:

#include <stdio.h>
#include <limits.h>

#define ARSZ 95

int mostoften (int *a);
int leastoften (int *a);

您的tools.c 为:

#include "tools.h"

int mostoften (int *a) {

    int i, max = INT_MIN, cha = '0';

    for (i = 0; i < ARSZ; i++)
        if (a[i] > max) {
            max = a[i];
            cha = i + ' ';
        }

    printf ("char '%c' : %d times\n", cha, max);

    return max;
}

int leastoften (int *a) {

    int i, min = INT_MAX, cha = '0';

    for (i = 0; i < ARSZ; i++)
        if (a[i] < min) {
            min = a[i];
            cha = i + ' ';
        }

    printf ("char '%c' : %d times\n", cha, min);

    return min;
}

您知道,如果maxmin 对于两个不同的字符相同,您将选择第一个,而对于leastoften,您将始终选择0 频率的第一个字符.要纠正这个问题,您需要保留第二个数组(或二维数组或结构)来跟踪输入中出现的字符,并且只考虑这些字符的频率。

最后,你的main.c 可以写成这样:

#include "tools.h"

int main (int argc, char **argv) {

    int c = 0, count[ARSZ] = {0};

    while ((c = getchar ()) != EOF)
        if (' ' <= c && c <= '~')
            count[c - ' ']++;

    if (argc > 1 && *argv[1])  /* check argc & not empty-string */
        switch (argv[1][1]) {
            case 'm':
                mostoften (count);
                break;
            case 'M':
                mostoften (count);
                break;
            case 'l':
                leastoften (count);
                break;
            case 'L':
                leastoften (count);
                break;
            default:
                fprintf (stderr, "warning: unrecognized option, using "
                                 "'mostoften'.\n");
                mostoften (count);
        }
    else {
        fprintf (stderr, "warning: no option given using 'mostoften'.\n");
        mostoften (count);
    }

    return 0;
}

有许多不同的方法可以完成此任务,但鉴于您的初始代码,这与您的意图保持一致。看看它,如果你有任何问题,请告诉我。如果您想要最简单的方法来跟踪输入中存在的字符而不使用结构,那么只需将count 声明为count[ARSZ][2] 并使用附加元素来指示存在哪些字符就可以了。 (您可以将数组作为int a[][2]int (*a)[2] 传递给您的函数)祝您好运。

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多