簡體   English   中英

在C語言中使用getchar()讀取輸入時是否需要分配內存?

[英]Does memory need to be allocated when reading input with getchar() in C?

在下面的代碼中,是否應該使用諸如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 = '\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文件,然后檢查用於單個控件表達式中的行尾。 &&評估其左側,並且僅在無法從左側的值確定布爾類型01int的結果時才評估其右側。 這種特性稱為快捷方式評估 ,適用於|| 和三元運算符? / :也。
  • c必須具有可以容納所有由getchar()重新調整的值的類型:所有類型為unsigned char和特殊負值EOF值。 charsigned charunsigned char都不適合此操作,因為c == EOF對於簽名char情況將不正確地匹配\\377 (在ISO-8859-1中為'ÿ' ),或者對於unsigned 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("%d\n", 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 ,后者只能容納字符值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM