使用 C 語言中的 getchar 函式
本文將演示關於如何使用 C 語言中的 getchar
函式的多種方法。
在 C 語言中使用 getchar
函式從標準輸入流中讀取單個字元
getchar
函式是 C 庫中標準輸入/輸出實用程式的一部分。字元輸入/輸出操作有多個函式,如 fgetc
、getc
、fputc
或 putchar
。fgetc
和 getc
的功能基本相當;它們取檔案流指標讀取一個字元,並將其以 unsigned char
的形式轉換為 int
型別返回。
請注意,getchar
是 getc
的特殊情況,它隱含地傳遞了 stdin
檔案流作為引數來讀取字元。因此,getchar
不需要任何引數,並將讀取的字元轉換為 int
型別返回。在下面的例子中,我們演示了用 putchar
函式輸入一個字元並列印的基本情況。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
printf("Please, input a single character: ");
ch = getchar();
putchar(ch);
exit(EXIT_SUCCESS);
}
在 C 語言中使用 getchar
函式讀取字串輸入
或者,我們可以實現一個迴圈來讀取輸入的字串,直到遇到新的行或 EOF
,並將其儲存在一個預先分配的 char
緩衝區。不過要注意,與呼叫 gets
或 getline
相比,這種方法會增加效能開銷,而 gets
或 getline
是實現同樣功能的庫函式。解決方案的主要部分是一個 while
迴圈,執行到 getchar
函式返回的值不等於新的行字元或 EOF
。
在這種情況下,我們任意分配一個大小為 20 個字元的 char
陣列。每一次迭代,都會實現陣列中第一個元素的指標,並將 getchar
的返回值分配給它。最後,我們用 printf
函式呼叫輸出緩衝區。
#include <stdio.h>
#include <stdlib.h>
enum { SIZE = 20 };
int main(void)
{
char buf[SIZE];
char *p;
int ch;
p = buf;
printf("Please, provide input: ");
while ((ch = getchar()) != '\n' && ch != EOF) {
*p++ = (char)ch;
}
*p++ = 0;
if (ch == EOF) {
printf("EOF encountered\n");
}
printf("%s\n", buf);
exit(EXIT_SUCCESS);
}
輸出:
Please, provide input: string longer than 20 characters
string longer than 20 characters
儘管前面的例子程式碼通常都能正常工作,但它有幾個錯誤,可能導致緩衝區溢位錯誤或程式異常終止。由於我們處理使用者輸入的內容直到遇到新的行或 EOF
,所以不能保證它能裝進固定大小的 char
緩衝區。如果我們必須使用固定緩衝區,我們要負責統計輸入的大小,並在達到容量後停止在緩衝區中儲存。
在前面的程式碼中我們解決了這個問題後,我們要處理使用%s
指定符列印緩衝區內容的 printf
語句。需要注意的是,並不能保證輸入字串的最後一個字元是空位元組,所以如果使用者自己沒有在緩衝區的最後插入空位元組,printf
呼叫就不知道停在哪裡。下面的示例程式碼糾正了之前的錯誤,並增加了一些行數,以便更好的演示。
#include <stdio.h>
#include <stdlib.h>
enum { SIZE = 20 };
int main(void)
{
char buf[SIZE];
int ch;
size_t index = 0;
size_t chars_read = 0;
printf("Please, provide input: ");
while ((ch = getchar()) != '\n' && ch != EOF) {
if (index < sizeof(buf) - 1) {
buf[index++] = (char)ch;
}
chars_read++;
}
buf[index] = '\0';
if (ch == EOF) {
printf("EOF encountered\n");
}
if (chars_read > index) {
printf("Truncation occured!\n");
}
printf("%s\n", buf);
exit(EXIT_SUCCESS);
}
輸出:
Please, provide input: string longer than 20 characters
Truncation occured!
string longer than
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn