在 C 中使用 getchar() 读取输入时是否需要分配内存?



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

char *c;
int count = 0;
while( (*c=getchar()) != 'n' ){
c++;
count++;
}

发布的代码有问题:

  • 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 = '';
else
buf[limit] = '';
printf("%sn", 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 failuren");
return 1;
}
while ((c = getchar()) != EOF && c != 'n') {
if (count < limit)
*p++ = c;
count++;
}
if (count < limit)
*p = '';
else
buf[limit] = '';
printf("%sn", buf);
free(buf);
return 0;
}

笔记:

  • while ((c = getchar()) != EOF && c != 'n')是一个经典的 C 习惯用法,用于从标准输入中读取一个字节,并将其存储在int变量c中,检查 end if 文件并在单个控制表达式中检查行尾。&&首先计算其左侧,并且仅当无法从左侧的值确定结果(0或类型为int的布尔值或1时,才计算其右侧。这种特性称为快捷求值,也适用于||和三元运算符?/:
  • c必须有一个类型,可以容纳由getchar()重新调整的所有值:类型unsigned char的所有值和特殊的负值EOFcharsigned charunsigned char都不适合这样做,因为c == EOF要么错误地匹配377(ISO-8859-1 中的'ÿ'(对于已签名的char案例,要么永远不会匹配未签名的char案例。intc的正确类型。

是的,应该的。

但是你在这里真的不需要指针。getchar()返回一个int

从文档中我们可以看到getchar的原型如下所示:

int getchar(void)

它不返回指针,所以是的,如果你想以你的方式使用指针,你必须确保它指向某物。实际上,您的代码会发出以下警告:

warning: assignment makes pointer from integer without a cast [-Wint-conversion]
while( (c=getchar()) != 'n' ){
^

您不一定需要使用malloc本身,但您必须确保c指向有效的地址。而且,由于您正在递增c因此您还负责确保这些地址有效。

简短回答:是的,需要分配内存。

这不仅仅是getchar-任何时候你都有一个像

char *c;

您必须仔细考虑它指向的位置,以及那里是否有任何分配的内存。

事实上,如果你说的只是

char *c;

不知道指针c指向哪里,所以你不知道那里是否有任何分配的内存,但如果我们必须猜测,我们不得不说可能没有。

谚语

char *c;

然后问指针c指向哪里就像说

int i;

然后问什么

printf("%dn", i);

将打印。 由于我们没有将i设置为任何值,因此我们不知道它将打印什么。

如果你想读取几个字符,并将它们存储在一个数组中,并使用指针来做到这一点,你可以 - 但你需要分配数组,并使指针指向它。 它可能看起来像这样。 顺便说一下,此时我将指针变量的名称更改为p,这是指针的更常用名称。 (c听起来像一个字符,而不是指向字符的指针。

char *p;
char arr[10];
int count = 0;
p = &arr[0];
while( (*p=getchar()) != 'n' ){
p++;
count++;
}

现在指针变量p有指向的位置,因此使用它来存储带有*p=getchar()字符是有效的。

话虽如此,我们有两个非常大的问题。 一种是数组被声明为足够大以容纳 10 个字符,但填充数组的循环确实会注意检查这一点。 如果有人在按 Enter 或 Return 之前键入 10 个或更多字符,p将离开为阵列分配的空间的末端,并开始覆盖其他内存,就像您担心的那样。

第二个困难是我们没有检查文件结尾。 此外,我们无法正确检查文件结尾,因为文件结束指示符EOF不是有效的字符值,因此不适合*p,它只能保存字符值。

相关内容

  • 没有找到相关文章