首页 > 解决方案 > 在 C 中使用 getchar() 读取输入时是否需要分配内存?

问题描述

在下面的代码中,是否应该c使用函数为指针分配内存malloc()?我担心递增c可能会导致它指向另一个变量,因此在*c = getchar()被调用时会覆盖它。

char *c;
int count = 0;

while( (*c=getchar()) != '\n' ){
    c++;
    count++;
}

标签: cmemorycharmallocgetchar

解决方案


贴出的代码有问题:

  • c未初始化,写入它会立即产生未定义的行为,增加它只会使情况变得更糟。
  • 您不测试文件结尾,也不测试任何数组边界,因此即使c指向实际数组、静态、自动或动态从堆分配的malloc(),您也必须检查是否c保持在边界内那个数组。

这是一个更正的版本:

#include <stdio.h>

int main() {
    char buf[100];
    int c, count, limit;
    char *p;

    p = buf;                  /* p points to an automatic array, no malloc needed */
    count = 0;
    limit = sizeof(buf) - 1;  /* maximum number of characters to store */

    while ((c = getchar()) != EOF && c != '\n') {
        if (count < limit)
           *p++ = c;
        count++;
    }
    if (count < limit)
        *p = '\0';
    else
        buf[limit] = '\0';

    printf("%s\n", buf);
    return 0;
}

这是一个内存分配:

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

int main() {
    char *buf, *p;
    int c, count, limit;

    limit = 99;
    p = buf = malloc(limit + 1);   /* p points to an array allocated from the heap */
    count = 0;

    if (buf == NULL) {
        printf("allocation failure\n");
        return 1;
    }

    while ((c = getchar()) != EOF && c != '\n') {
        if (count < limit)
           *p++ = c;
        count++;
    }
    if (count < limit)
        *p = '\0';
    else
        buf[limit] = '\0';

    printf("%s\n", buf);
    free(buf);
    return 0;
}

笔记:

  • while ((c = getchar()) != EOF && c != '\n')是一个经典的 C 习惯用法,从标准输入中读取一个字节,并将其存储在一个int变量c中,检查 end if 文件并检查单个控制表达式中的行尾。&&首先评估其左侧,并且仅在无法从左侧的值确定结果(布尔值01类型)时才评估其右侧。int这种特性称为快捷评估,也适用于||三元运算符?/ :
  • c必须有一个类型,可以容纳所有返回的值getchar():所有类型unsigned char的值和特殊的负值EOF。既不char也不适合这一点,因为要么不正确地匹配signed char(在ISO-8859-1 中)有符号的情况,要么永远不匹配无符号的情况。是正确的类型。unsigned charc == EOF\377'ÿ'charcharintc

推荐阅读