【问题标题】:Dynamic memory allocation for input? [closed]输入的动态内存分配? [关闭]
【发布时间】:2014-03-18 20:28:36
【问题描述】:

我在开始我的项目时遇到了很多麻烦。以下是路线:

"Complete counts.c as follows:
    Read characters from standard input until EOF (the end-of-file mark) is read. Do not prompt the user to enter text - just read data as soon as the program starts.
    Keep a running count of each different character encountered in the input, and keep count of the total number of characters input (excluding EOF)."

我的教授给我的开始格式是:`

#include <stdio.h>
int main(int argc, char *argv[]) {
return 0;
}

除了如何开始这个问题,我也很困惑为什么在没有任何东西传递给它的情况下,为什么在 main 函数中给出了两个参数。帮助将不胜感激!谢谢!

`

【问题讨论】:

    标签: c memory-management scanf dynamic-memory-allocation argc


    【解决方案1】:

    在这里查看您遇到的问题有点棘手。标题不是一个完整的问题,正文中也没有;他们似乎在暗示完全不同的问题。

    作业告诉您读取字符 - 而不是存储它们。如果您愿意,您可以有一个循环,一次只读取一个(例如,使用 getchar)。您还被要求报告每个字符的计数,这对存储在数组中是有意义的。鉴于这是“每个不同的字符”,最简单的方法是为所有可能的字符调整数组的大小(limits.h 定义了 UCHAR_MAX,这将对此有所帮助)。如果数组是自动分配的(函数局部变量的默认值),请记住初始化数组。

    关于 main 的参数,这个程序不需要它们,而且 C 标准允许您将它们排除在外。它们很可能包含在内,因为这是基本 C 程序的模板,以便在也使用命令行参数时使其可用。

    有关更多参考代码,您可能需要比较字数统计实用程序 (wc);您想要的字符计数是频率分析或直方图的基础。

    【讨论】:

      【解决方案2】:

      这应该让您开始调查完成任务需要学习什么,

      最初声明一个足够大的字符输入缓冲区来读取字符,

      char input[SIZE];
      

      使用fgets()从标准输入读取字符,

      if (fgets(input, sizeof input, stdin) == NULL) {
           ;  // handle EOF
      }
      

      现在input 数组有你的字符串,你可以找到出现的字符。我不明白当你说要计算不同的字符时,但是你有一个数组可以完全遍历它来计算你需要的字符。

      【讨论】:

        【解决方案3】:

        首先,幸运的是,我们在这里根本不需要动态内存分配,因为我们不需要存储输入字符串,相反,我们只需要记录在程序运行期间输入了每个 ascii 代码的数量,因为有我们可以简单地将它们存储在一个固定大小的数组中。

        我们在这里查看的函数(假设我们使用标准库)如下:

        • getchar,从标准输入读取字符
        • printf,将输出打印回标准输出

        我们需要的结构是:

        • do {} while,循环直到条件为假

        剩下的只需要简单的数学运算符,这里有一个简短的例子,基本上展示了一个示例解决方案:

        #include <stdio.h>
        int main(int argc, char *argv[])
        {
            /* Create an array with entries for each char,
             * then init it to zeros */
            int AsciiCounts[256] = {0};
            int ReadChar;
            int TotalChars = 0;
            int Iterator = 0;
            do
            {
                /* Read a char from stdin */
                ReadChar = getchar();
                /* Increment the entry for its code in the array */
                AsciiCounts[ReadChar]++;
                TotalChars++;
            } while (ReadChar != EOF);
            /* Stop if we read an EOF */
            do
            {
                /* Print each char code and how many times it occurred */
                printf("Char code %#x occurred %d times\n", Iterator, AsciiCounts[Iterator]);
                Iterator++;
            } while (Iterator <= 255);
            /* Print the total length read in */
            printf("Total chars read (excluding EOF): %d", --TotalChars);
            return 0;
        }
        

        这应该实现基本目标,但是一些扩展练习可能有助于您对 C 的理解。首先,您可以尝试将第二个 do while 循环转换为 for 循环,这更适合这种情况,但我为了简单起见,没有使用。其次,您可以添加一个条件,以便输出阶段跳过从未发生过的代码。最后,检查哪些字符是可打印的并打印它们的值而不是它们的十六进制代码可能会很有趣。

        在问题的第二部分,这些参数被传递给 main 即使它们被忽略的原因是由于大多数操作系统下 c 程序的标准调用约定,它们传递了命令行参数的数量和每个参数的值命令行参数分别在程序希望检查它们的情况下。但是,如果您真的不使用它们,您可以在大多数编译器中只使用 main() 来代替,但是如果您选择添加命令行选项并且没有性能优势,这会使以后的事情变得更加困难。

        【讨论】:

        • 请不要只把完整的解决方案交给家庭作业。顺便说一句,为什么将 for 循环拆分为单独的行,其中一个留在另一个循环的另一侧?
        • 对不起,我假设提问者的编程经验为 0,所以认为仔细解释的答案以及一些扩展将有助于他学习(似乎他没有经验在此阶段从头开始),但如果您对此事有不同意见,请随时编辑答案以使其不那么完整。虽然我不太明白你所说的拆分循环是什么意思,但我编码为“Allman 风格”缩进,这是我工作场所的事实标准。
        • 我不是指缩进。我的意思是循环处理迭代器,通常会使用for(int i=0; i&lt;=UCHAR_MAX; i++) { printf(...); }而不是do..while来编写。
        • 哦,我实际上在答案中解释了这一点,如果您阅读:“首先您可以尝试将第二个 do while 循环转换为 for 循环,这更适合这种情况,但我没有为简单起见使用。”
        • 它说简单(抱歉之前没有仔细阅读)。我只是不认为它更简单。它似乎只是不太清楚,尽管可以说它更加一致,因为只有一种类型的循环。
        猜你喜欢
        • 1970-01-01
        • 2018-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多