欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c語言中比較特殊的輸入函數(shù)舉例詳解

 更新時(shí)間:2024年09月10日 10:55:29   作者:小容小容  
C語言提供了豐富的標(biāo)準(zhǔn)庫函數(shù),用于處理各種輸入輸出操作,下面這篇文章主要介紹了c語言中比較特殊的輸入函數(shù)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一.getchar()函數(shù)

getchar()是C語言中的一個(gè)標(biāo)準(zhǔn)庫函數(shù),用于從標(biāo)準(zhǔn)輸入(通常是鍵盤)讀取一個(gè)字符。它是stdio.h庫的一部分,常用于簡單的字符輸入操作。

1.基本功能

getchar()讀取標(biāo)準(zhǔn)輸入中的下一個(gè)字符,并將其作為一個(gè)int類型的值返回。盡管返回值是int類型,但它實(shí)際上是一個(gè)字符的ASCII值。

2.使用方法

int ch = getchar();

在這段代碼中,getchar()從標(biāo)準(zhǔn)輸入中讀取一個(gè)字符,并將其返回的字符值存儲(chǔ)在ch變量中。

示例:

(1).讀取單個(gè)字符

#include <stdio.h>

int main() {
    int ch;
    
    printf("請輸入一個(gè)字符: ");
    ch = getchar();
    
    printf("你輸入的字符是: %c\n", ch);
    
    return 0;
}

解釋:

  • 程序等待用戶輸入一個(gè)字符。用戶輸入的字符被getchar()讀取并存儲(chǔ)在ch中。
  • printf函數(shù)隨后輸出用戶輸入的字符。

(2).讀取多個(gè)字符(直到遇到換行符)

#include <stdio.h>

int main() {
    int ch;
    
    printf("請輸入一行文字,按回車結(jié)束: ");
    
    while ((ch = getchar()) != '\n' && ch != EOF) {
        printf("讀取字符: %c\n", ch);
    }
    
    printf("輸入結(jié)束。\n");
    
    return 0;
}

解釋:

  • 程序使用while循環(huán)來讀取字符,直到遇到換行符('\n')或文件結(jié)束符(EOF)。
  • 每次讀取的字符都會(huì)被輸出。

(3).處理輸入中的空白字符

#include <stdio.h>

int main() {
    int ch;

    printf("請輸入字符,輸入結(jié)束請按 Ctrl+D (Linux) 或 Ctrl+Z (Windows):\n");

    while ((ch = getchar()) != EOF) {
        if (ch == ' ' || ch == '\n' || ch == '\t') {
            printf("[空白字符]\n");
        } else {
            printf("讀取字符: %c\n", ch);
        }
    }

    printf("輸入結(jié)束。\n");
    
    return 0;
}

解釋:

  • 這個(gè)程序讀取用戶輸入的每個(gè)字符,并檢查它是否是空白字符(空格、換行符、制表符)。
  • 如果是空白字符,程序會(huì)輸出[空白字符],否則輸出字符本身。
  • 當(dāng)用戶按下Ctrl+DCtrl+Z時(shí),輸入結(jié)束。

3.返回值

  • 讀取的字符: 如果讀取成功,getchar()返回讀取的字符的ASCII值。例如,如果用戶輸入字符'A',getchar()將返回值65(即'A'的ASCII碼)。

  • EOF (End of File): 如果在讀取時(shí)遇到文件結(jié)束符(通常是在控制臺輸入時(shí)按下Ctrl+DCtrl+Z),getchar()將返回常量EOF,其值通常為-1。EOF用于指示輸入的結(jié)束或錯(cuò)誤情況。

4.應(yīng)用場景

  • 簡單字符輸入getchar()通常用于簡單的字符輸入操作,例如讀取單個(gè)字符或控制臺中的用戶輸入。

  • 處理空白字符: 當(dāng)你需要明確處理空白字符(例如空格、制表符或換行符)時(shí),getchar()特別有用。相比于scanf,getchar()不會(huì)跳過空白字符,因此你可以逐字符地處理輸入。

  • 控制輸入流getchar()在處理輸入流時(shí)非常靈活,可以用于跳過不需要的字符。例如,在多行輸入或復(fù)雜輸入格式的情況下,它可以幫助你控制和過濾輸入內(nèi)容。

5.注意事項(xiàng)

  • 返回類型為int: 盡管getchar()用于讀取單個(gè)字符,但它的返回類型是int而不是char。這樣設(shè)計(jì)是為了能夠返回EOF來表示文件結(jié)束或錯(cuò)誤。為了避免潛在的錯(cuò)誤,通常應(yīng)該使用int類型來存儲(chǔ)getchar()的返回值。

  • 緩沖區(qū)問題: 在控制臺輸入時(shí),用戶輸入的內(nèi)容通常會(huì)先進(jìn)入緩沖區(qū)。當(dāng)按下回車鍵時(shí),緩沖區(qū)中的內(nèi)容才會(huì)被getchar()逐個(gè)讀取。因此,getchar()不會(huì)在每個(gè)字符輸入時(shí)立即返回,而是等待用戶按下回車鍵。

  • 錯(cuò)誤處理: 當(dāng)使用getchar()時(shí),程序應(yīng)該考慮EOF的可能性,尤其是在文件輸入或批處理輸入的情況下。忽略這一點(diǎn)可能會(huì)導(dǎo)致程序未正確處理輸入結(jié)束的情況。

二.fgets()函數(shù)

fgets 是C語言中用于從文件流中讀取一行字符串的標(biāo)準(zhǔn)庫函數(shù)。它提供了一種安全、方便的方法來讀取輸入,避免了諸如緩沖區(qū)溢出等常見問題。fgets 通常用于讀取用戶輸入、從文件中讀取數(shù)據(jù)等場景。

1.函數(shù)原型

char *fgets(char *str, int n, FILE *stream);

  • str: 指向字符數(shù)組的指針,fgets 會(huì)將讀取到的字符串存儲(chǔ)在該數(shù)組中。
  • n: 要讀取的最大字符數(shù),包括結(jié)尾的空字符 \0。也就是說,fgets 最多讀取 n-1 個(gè)字符。
  • stream: 輸入流指針,指明從哪個(gè)流中讀取數(shù)據(jù)。常見的流有標(biāo)準(zhǔn)輸入流 stdin,文件流等。

返回值

  • 成功: 返回指向讀取字符串的指針,即參數(shù) str。
  • 失敗或到達(dá)文件末尾: 返回 NULL

2.工作原理

fgets 函數(shù)從指定的輸入流 stream 中讀取字符,并將其存儲(chǔ)到 str 指向的字符數(shù)組中,直到發(fā)生以下任一情況:

讀取了 (n - 1) 個(gè)字符: 為了保證字符串以 \0 結(jié)尾,fgets 最多讀取 n - 1 個(gè)字符。

遇到換行符 \nfgets 會(huì)讀取換行符,并將其存儲(chǔ)在 str 中。

到達(dá)文件末尾 EOF: 如果在讀取過程中遇到文件末尾,讀取操作結(jié)束。

讀取完成后,fgets 會(huì)在讀取的字符串末尾自動(dòng)添加一個(gè)空字符 \0,以表示字符串的結(jié)束。

3.使用示例

(1).從標(biāo)準(zhǔn)輸入讀取一行字符串

#include <stdio.h>

int main() {
    char buffer[100];

    printf("請輸入一行文本:");
    if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        printf("您輸入的是:%s", buffer);
    } else {
        printf("讀取輸入時(shí)發(fā)生錯(cuò)誤。\n");
    }

    return 0;
}

解釋:

  • fgets(buffer, sizeof(buffer), stdin) 從標(biāo)準(zhǔn)輸入讀取最多 99 個(gè)字符(保留1個(gè)字符給 \0),并存儲(chǔ)在 buffer 中。
  • 如果讀取成功,程序會(huì)輸出用戶輸入的內(nèi)容。

注意: 由于 fgets 會(huì)將換行符 \n 一并讀取并存儲(chǔ),如果不想要這個(gè)換行符,需要手動(dòng)去除。

(2).從文件中讀取內(nèi)容

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp == NULL) {
        perror("無法打開文件");
        return 1;
    }

    char line[256];
    while (fgets(line, sizeof(line), fp) != NULL) {
        printf("%s", line);
    }

    fclose(fp);
    return 0;
}

解釋:

  • 打開名為 example.txt 的文件,讀取其中的內(nèi)容并逐行打印到標(biāo)準(zhǔn)輸出。
  • fgets 在每次循環(huán)中讀取一行內(nèi)容,直到文件結(jié)束。

4.處理換行符

正如前面提到的,fgets 會(huì)將輸入中的換行符 \n 一并讀取并存儲(chǔ)在目標(biāo)字符串中。如果在處理時(shí)不需要這個(gè)換行符,可以使用以下方法去除:

方法1:手動(dòng)檢查并替換

size_t len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {
    buffer[len - 1] = '\0';
}

解釋:

  • 首先獲取字符串的長度 len。
  • 如果最后一個(gè)字符是 \n,將其替換為 \0。

方法2:使用 strcspn 函數(shù)

buffer[strcspn(buffer, "\n")] = '\0';

解釋:

  • strcspn 函數(shù)返回 buffer 中第一個(gè)匹配 \n 的位置索引,然后將該位置的字符替換為 \0。

5.與其他輸入函數(shù)的比較

(1). fgets vs gets

  • gets: 從標(biāo)準(zhǔn)輸入讀取一行,直到遇到換行符或文件結(jié)束符。不安全,因?yàn)闊o法指定讀取的最大長度,容易導(dǎo)致緩沖區(qū)溢出。

  • fgets: 可以指定最大讀取長度,安全性更高。建議始終使用 fgets 代替 gets

(2). fgets vs scanf

  • scanf: 按照指定的格式從輸入中讀取數(shù)據(jù),默認(rèn)會(huì)忽略空白字符,讀取字符串時(shí)會(huì)在遇到空白字符時(shí)停止。

  • fgets: 讀取整行輸入,包括空白字符和換行符,更適合讀取包含空格的字符串

示例:

char str1[100], str2[100];

// 使用 scanf
scanf("%s", str1);
// 輸入:Hello World
// str1 的值為:"Hello"

// 使用 fgets
fgets(str2, sizeof(str2), stdin);
// 輸入:Hello World
// str2 的值為:"Hello World\n"

(3). fgets vs fgetc

  • fgetc: 每次從指定流中讀取一個(gè)字符,適合逐字符處理輸入。

  • fgets: 一次讀取一行或指定長度的字符串,效率更高。

6、常見錯(cuò)誤和注意事項(xiàng)

(1). 忘記檢查返回值

在使用 fgets 時(shí),應(yīng)該始終檢查其返回值,以確保讀取成功。

錯(cuò)誤示例:

fgets(buffer, sizeof(buffer), stdin);
// 未檢查返回值,可能導(dǎo)致程序處理空指針

正確示例:

if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
    // 處理讀取的數(shù)據(jù)
} else {
    // 錯(cuò)誤處理
}

(2). 未正確處理換行符

如前所述,fgets 會(huì)保留輸入中的換行符,如果不想要這個(gè)換行符,需要手動(dòng)去除。

(3). 緩沖區(qū)大小不足

確保提供給 fgets 的緩沖區(qū)足夠大,以容納預(yù)期的輸入數(shù)據(jù)和結(jié)尾的空字符。

錯(cuò)誤示例:

char buffer[10];
fgets(buffer, 100, stdin); // 錯(cuò)誤:緩沖區(qū)只有10個(gè)字節(jié),卻試圖讀取100個(gè)字符

正確示例:

char buffer[100];
fgets(buffer, sizeof(buffer), stdin); // 正確:緩沖區(qū)大小與讀取長度匹配

(4). 多次讀取時(shí)的緩沖區(qū)殘留

在某些情況下,輸入流中可能殘留未讀取的字符,需要在下一次讀取前清空緩沖區(qū)。

char buffer1[50], buffer2[50];

printf("輸入第一行:");
fgets(buffer1, sizeof(buffer1), stdin);

printf("輸入第二行:");
fgets(buffer2, sizeof(buffer2), stdin);

如果在第一次輸入時(shí)輸入的字符超過了 buffer1 的大小,剩余的字符會(huì)留在輸入緩沖區(qū)中,影響第二次讀取。為避免這種情況,可以在每次讀取后清空緩沖區(qū)。

清空緩沖區(qū)的方法:

int c;
while ((c = getchar()) != '\n' && c != EOF);

7.綜合示例

示例:讀取用戶輸入并處理

#include <stdio.h>
#include <string.h>

int main() {
    char name[50];
    int age;
    char input[100];

    // 讀取姓名
    printf("請輸入您的姓名:");
    if (fgets(name, sizeof(name), stdin) != NULL) {
        // 去除換行符
        name[strcspn(name, "\n")] = '\0';
    } else {
        printf("讀取姓名失敗。\n");
        return 1;
    }

    // 讀取年齡
    printf("請輸入您的年齡:");
    if (fgets(input, sizeof(input), stdin) != NULL) {
        // 將字符串轉(zhuǎn)換為整數(shù)
        age = atoi(input);
    } else {
        printf("讀取年齡失敗。\n");
        return 1;
    }

    printf("姓名:%s,年齡:%d\n", name, age);

    return 0;
}

解釋:

  • 首先使用 fgets 讀取用戶的姓名,并去除結(jié)尾的換行符。
  • 然后再次使用 fgets 讀取用戶的年齡輸入,并使用 atoi 將其轉(zhuǎn)換為整數(shù)。
  • 最后輸出用戶輸入的信息。

三.sscanf函數(shù)

sscanf 是C語言中用于從字符串中讀取并解析數(shù)據(jù)的標(biāo)準(zhǔn)庫函數(shù)。它的作用類似于 scanf,但 sscanf 從字符串中讀取數(shù)據(jù),而 scanf 是從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)。sscanf 非常適合從已知格式的字符串中提取數(shù)值、字符等數(shù)據(jù)。

1.函數(shù)原型

int sscanf(const char *str, const char *format, ...);

  • str: 要解析的源字符串。sscanf 會(huì)從這個(gè)字符串中讀取數(shù)據(jù)。
  • format: 格式字符串,指定了要解析的數(shù)據(jù)格式。它的語法和 scanf 的格式字符串相同,包括各種格式說明符(如 %d%s%f 等)。
  • ...: 可變參數(shù)列表,提供用于存儲(chǔ)從字符串中讀取的數(shù)據(jù)的指針。

返回值

  • 成功: 返回成功讀取并匹配的項(xiàng)數(shù)。
  • 失敗: 返回 EOF,如果在解析過程中遇到錯(cuò)誤或在嘗試讀取時(shí)到達(dá)字符串末尾

2.工作原理

sscanf 函數(shù)根據(jù) format 字符串中的格式說明符,從源字符串 str 中逐一讀取和解析數(shù)據(jù)。每個(gè)格式說明符都對應(yīng)于一個(gè)傳入的變量地址,sscanf 將解析后的數(shù)據(jù)存儲(chǔ)在這些變量中。

格式說明符示例

  • %d: 讀取一個(gè)整數(shù)。
  • %f: 讀取一個(gè)浮點(diǎn)數(shù)。
  • %s: 讀取一個(gè)字符串,遇到空白字符(如空格、換行)時(shí)停止。
  • %c: 讀取單個(gè)字符。

示例:

(1).從字符串中解析數(shù)據(jù)

#include <stdio.h>

int main() {
    const char *str = "100 3.14 hello";
    int num;
    float pi;
    char word[20];

    int count = sscanf(str, "%d %f %s", &num, &pi, word);

    printf("讀取到 %d 項(xiàng)數(shù)據(jù):\n", count);
    printf("整數(shù): %d\n", num);
    printf("浮點(diǎn)數(shù): %.2f\n", pi);
    printf("字符串: %s\n", word);

    return 0;
}

輸出:

讀取到 3 項(xiàng)數(shù)據(jù):
整數(shù): 100
浮點(diǎn)數(shù): 3.14
字符串: hello

解釋:

  • sscanf 解析字符串 "100 3.14 hello",并將數(shù)據(jù)分別存儲(chǔ)在 numpiword 中。
  • 返回值 count 表示成功讀取了3項(xiàng)數(shù)據(jù)。

3.常見用法和注意事項(xiàng)

(1). 解析特定格式的字符串

sscanf 特別適用于解析具有固定格式的字符串,比如日期、時(shí)間、IP地址等。

示例:解析日期

#include <stdio.h>

int main() {
    const char *date = "2024-08-17";
    int year, month, day;

    sscanf(date, "%d-%d-%d", &year, &month, &day);

    printf("年: %d, 月: %d, 日: %d\n", year, month, day);

    return 0;
}

輸出:

年: 2024, 月: 8, 日: 17

解釋:

  • 解析字符串 "2024-08-17" 中的年份、月份和日期,并分別存儲(chǔ)在 yearmonthday 中。

(2). 處理多余的輸入

如果源字符串中的內(nèi)容多于格式說明符指定的內(nèi)容,sscanf 只會(huì)處理指定的部分,忽略其余部分。

示例:部分解析字符串

#include <stdio.h>

int main() {
    const char *str = "42 3.14 some extra text";
    int num;
    float pi;

    int count = sscanf(str, "%d %f", &num, &pi);

    printf("讀取到 %d 項(xiàng)數(shù)據(jù):\n", count);
    printf("整數(shù): %d\n", num);
    printf("浮點(diǎn)數(shù): %.2f\n", pi);

    return 0;
}

輸出:

讀取到 2 項(xiàng)數(shù)據(jù):
整數(shù): 42
浮點(diǎn)數(shù): 3.14

解釋:

  • sscanf 只解析了前兩個(gè)數(shù)據(jù)項(xiàng)(整數(shù)和浮點(diǎn)數(shù)),忽略了字符串末尾的額外內(nèi)容。

(3). 不匹配的格式

如果字符串中的內(nèi)容與格式說明符不匹配,sscanf 會(huì)停止解析,并返回已成功讀取的項(xiàng)數(shù)。

示例:格式不匹配

#include <stdio.h>

int main() {
    const char *str = "hello 3.14";
    int num;
    float pi;

    int count = sscanf(str, "%d %f", &num, &pi);

    printf("讀取到 %d 項(xiàng)數(shù)據(jù):\n", count);
    return 0;
}

輸出:

讀取到 0 項(xiàng)數(shù)據(jù):

(4). 忽略特定數(shù)據(jù)

sscanf 還可以使用 * 來忽略某些輸入數(shù)據(jù),不存儲(chǔ)在任何變量中。

示例:忽略數(shù)據(jù)

#include <stdio.h>

int main() {
    const char *str = "42 skip this 3.14";
    int num;
    float pi;

    sscanf(str, "%d %*s %f", &num, &pi);

    printf("整數(shù): %d\n", num);
    printf("浮點(diǎn)數(shù): %.2f\n", pi);

    return 0;
}

輸出:

整數(shù): 42
浮點(diǎn)數(shù): 3.14

解釋:

  • sscanf 使用 %*s 忽略了 "skip this" 字符串部分,只提取了整數(shù)和浮點(diǎn)數(shù)。

(5). 返回值處理

sscanf 的返回值用于檢查是否成功解析了預(yù)期的項(xiàng)數(shù)。在實(shí)際編程中,應(yīng)該根據(jù)返回值來驗(yàn)證解析操作的成功與否。

示例:檢查返回值

#include <stdio.h>

int main() {
    const char *str = "100 3.14";
    int num;
    float pi;

    int result = sscanf(str, "%d %f", &num, &pi);

    if (result == 2) {
        printf("成功讀取兩個(gè)數(shù)值:%d 和 %.2f\n", num, pi);
    } else {
        printf("解析失敗,已成功讀取 %d 項(xiàng)數(shù)據(jù)。\n", result);
    }

    return 0;
}

輸出:

成功讀取兩個(gè)數(shù)值:100 和 3.14

解釋:

  • 如果 sscanf 成功解析了兩個(gè)值,程序輸出成功消息。否則,輸出失敗消息。

4.常見錯(cuò)誤和陷阱

(1). 未匹配到預(yù)期的數(shù)據(jù)

如果輸入字符串的格式與格式說明符不匹配,sscanf 會(huì)停止解析,返回已經(jīng)成功解析的項(xiàng)數(shù)。確保格式字符串與輸入字符串的格式一致非常重要。

(2). 忘記檢查返回值

忽略 sscanf 的返回值可能導(dǎo)致錯(cuò)誤的程序行為。檢查返回值是驗(yàn)證解析操作成功與否的關(guān)鍵步驟。

(3). 緩沖區(qū)溢出

當(dāng)讀取字符串?dāng)?shù)據(jù)(如使用 %s)時(shí),確保目標(biāo)緩沖區(qū)有足夠的空間以避免溢出。使用長度限制格式符號(如 %99s)可以防止緩沖區(qū)溢出。

(4). 處理多余輸入

如果 sscanf 只讀取了部分輸入數(shù)據(jù),而程序的邏輯依賴于完整的數(shù)據(jù)解析,可能會(huì)導(dǎo)致問題。合理設(shè)計(jì)格式說明符和字符串輸入非常重要。

5.sscanf 與其他輸入函數(shù)的比較

(1). sscanf vs scanf

  • scanf: 從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù),適用于直接的用戶輸入操作。

  • sscanf: 從字符串中讀取數(shù)據(jù),適用于解析已經(jīng)存在的字符串內(nèi)容。

(2). sscanf vs fscanf

  • fscanf: 從文件流中讀取數(shù)據(jù),適用于從文件中解析數(shù)據(jù)。

  • sscanf: 從字符串中讀取數(shù)據(jù),適用于解析內(nèi)存中的字符串。

(3). sscanf vs strtok

  • strtok: 用于分割字符串,可以按指定的分隔符逐一提取子字符串。

  • sscanf: 直接解析字符串中的數(shù)據(jù),并將其轉(zhuǎn)換為相應(yīng)的數(shù)據(jù)類型。

6.綜合示例

示例:解析復(fù)雜字符串

#include <stdio.h>

int main() {
    const char *str = "Name: John Doe, Age: 30, Score: 85.5";
    char name[50];
    int age;
    float score;

    int count = sscanf(str, "Name: %[^,], Age: %d, Score: %f", name, &age, &score);

    if (count == 3) {
        printf("姓名: %s\n", name);
        printf("年齡: %d\n", age);
        printf("分?jǐn)?shù): %.1f\n", score);
    } else {
        printf("解析字符串失敗。\n");
    }

    return 0;
}

輸出:

姓名: John Doe
年齡: 30
分?jǐn)?shù): 85.5

解釋:

  • 使用 sscanf 從格式化字符串中提取姓名、年齡和分?jǐn)?shù)。%[^,] 格式說明符用于讀取直到遇到逗號 , 的所有字符,這樣可以處理包含空格的姓名。

四.fscanf()函數(shù)

fscanf 是C語言中用于從文件讀取并解析數(shù)據(jù)的標(biāo)準(zhǔn)庫函數(shù)。它的作用類似于 scanf,但 fscanf 從文件流中讀取數(shù)據(jù),而 scanf 是從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)。fscanf 適合從文件中逐行或逐項(xiàng)讀取并解析數(shù)據(jù)。

1.函數(shù)原型

int fscanf(FILE *stream, const char *format, ...);

參數(shù)說明

  • stream: 文件指針,指向要讀取的文件流(通常是通過 fopen 打開的文件)。
  • format: 格式字符串,指定了要解析的數(shù)據(jù)格式。它的語法和 scanf 的格式字符串相同,包括各種格式說明符(如 %d%s%f 等)。
  • ...: 可變參數(shù)列表,提供用于存儲(chǔ)從文件中讀取的數(shù)據(jù)的指針。

返回值

  • 成功: 返回成功讀取并匹配的項(xiàng)數(shù)
  • 失敗: 如果遇到文件結(jié)束符 EOF,則返回 EOF。如果遇到錯(cuò)誤,返回負(fù)數(shù)。

2.工作原理

fscanf 函數(shù)根據(jù) format 字符串中的格式說明符,從文件流 stream 中逐一讀取和解析數(shù)據(jù)。每個(gè)格式說明符都對應(yīng)于一個(gè)傳入的變量地址,fscanf 將解析后的數(shù)據(jù)存儲(chǔ)在這些變量中。

格式說明符示例

  • %d: 讀取一個(gè)整數(shù)。
  • %f: 讀取一個(gè)浮點(diǎn)數(shù)。
  • %s: 讀取一個(gè)字符串,遇到空白字符(如空格、換行)時(shí)停止。
  • %c: 讀取單個(gè)字符。

示例:從文件中解析數(shù)據(jù)

假設(shè)有一個(gè)文本文件 data.txt,內(nèi)容如下:

42 3.14 hello
#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r"); // 打開文件進(jìn)行讀取
    if (file == NULL) {
        perror("無法打開文件");
        return 1;
    }

    int num;
    float pi;
    char word[20];

    int count = fscanf(file, "%d %f %s", &num, &pi, word);

    printf("讀取到 %d 項(xiàng)數(shù)據(jù):\n", count);
    printf("整數(shù): %d\n", num);
    printf("浮點(diǎn)數(shù): %.2f\n", pi);
    printf("字符串: %s\n", word);

    fclose(file); // 關(guān)閉文件
    return 0;
}

輸出:

讀取到 3 項(xiàng)數(shù)據(jù):
整數(shù): 42
浮點(diǎn)數(shù): 3.14
字符串: hello

解釋:

  • fscanf 從文件 data.txt 中解析數(shù)據(jù),并將數(shù)據(jù)分別存儲(chǔ)在 numpiword 中。
  • 返回值 count 表示成功讀取了3項(xiàng)數(shù)據(jù)。

3.常用用法和注意事項(xiàng)

(1). 讀取一行數(shù)據(jù)

fscanf 通常按格式說明符讀取數(shù)據(jù),直到匹配結(jié)束,或者遇到文件結(jié)束符 EOF。它不會(huì)自動(dòng)處理行結(jié)束符,因此如果要按行讀取數(shù)據(jù),可以結(jié)合 fgets 和 sscanf 使用。

示例:逐行讀取數(shù)據(jù)

假設(shè)文件 data.txt 內(nèi)容如下:

42 3.14 hello
43 2.71 world
#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("無法打開文件");
        return 1;
    }

    int num;
    float pi;
    char word[20];

    while (fscanf(file, "%d %f %s", &num, &pi, word) != EOF) {
        printf("整數(shù): %d, 浮點(diǎn)數(shù): %.2f, 字符串: %s\n", num, pi, word);
    }

    fclose(file);
    return 0;
}

輸出:

整數(shù): 42, 浮點(diǎn)數(shù): 3.14, 字符串: hello
整數(shù): 43, 浮點(diǎn)數(shù): 2.71, 字符串: world

(2). 文件指針位置

fscanf 讀取數(shù)據(jù)后,文件指針會(huì)移動(dòng)到讀取結(jié)束的位置。下一次調(diào)用 fscanf 會(huì)從當(dāng)前文件指針位置繼續(xù)讀取。

(3). 遇到EOF

當(dāng) fscanf 遇到文件結(jié)束符 EOF 時(shí),它會(huì)返回 EOF,通常是 -1。這可以用來判斷是否已經(jīng)讀取到文件末尾。

(4). 忽略特定數(shù)據(jù)

類似于 sscanf,fscanf 也可以使用 * 來忽略某些輸入數(shù)據(jù),而不存儲(chǔ)在任何變量中。

示例:忽略數(shù)據(jù)

#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("無法打開文件");
        return 1;
    }

    int num;
    float pi;

    while (fscanf(file, "%d %*s %f", &num, &pi) != EOF) {
        printf("整數(shù): %d, 浮點(diǎn)數(shù): %.2f\n", num, pi);
    }

    fclose(file);
    return 0;
}

解釋:

  • fscanf 使用 %*s 忽略了字符串部分,只提取了整數(shù)和浮點(diǎn)數(shù)。

(5). 返回值處理

與 sscanf 類似,fscanf 的返回值表示成功讀取并解析的數(shù)據(jù)項(xiàng)數(shù)。在實(shí)際編程中,應(yīng)該根據(jù)返回值來驗(yàn)證解析操作的成功與否。

示例:檢查返回值

#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("無法打開文件");
        return 1;
    }

    int num;
    float pi;

    while (fscanf(file, "%d %f", &num, &pi) == 2) { // 期望成功讀取2項(xiàng)數(shù)據(jù)
        printf("整數(shù): %d, 浮點(diǎn)數(shù): %.2f\n", num, pi);
    }

    fclose(file);
    return 0;
}

解釋:

  • 只有在成功解析了兩個(gè)值時(shí)才輸出結(jié)果。如果 fscanf 未能成功讀取兩個(gè)值,將停止讀取。

(6). 處理多余輸入

如果文件中的內(nèi)容多于格式說明符指定的內(nèi)容,fscanf 只會(huì)處理指定的部分,忽略其余部分。

4.常見錯(cuò)誤和陷阱

(1). 格式不匹配

如果文件中的內(nèi)容與格式說明符不匹配,fscanf 會(huì)停止解析,并返回已成功讀取的項(xiàng)數(shù)。確保格式字符串與文件內(nèi)容格式一致非常重要。

(2). 忘記檢查返回值

忽略 fscanf 的返回值可能導(dǎo)致錯(cuò)誤的程序行為。檢查返回值是驗(yàn)證解析操作成功與否的關(guān)鍵步驟。

(3). 文件結(jié)束符

fscanf 在讀取到文件結(jié)束符 EOF 時(shí)會(huì)返回 EOF,這與常規(guī)的返回值檢查不同,處理文件結(jié)束符時(shí)需要特別注意。

5.fscanf 與其他輸入函數(shù)的比較

(1). fscanf vs scanf

  • scanf: 從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù),適用于直接的用戶輸入操作。

  • fscanf: 從文件流中讀取數(shù)據(jù),適用于從文件中解析數(shù)據(jù)。

(2). fscanf vs sscanf

  • sscanf: 從字符串中讀取數(shù)據(jù),適用于解析內(nèi)存中的字符串。

  • fscanf: 從文件流中讀取數(shù)據(jù),適用于從文件中解析數(shù)據(jù)。

(3). fscanf vs fgets

  • fgets: 從文件中讀取一整行字符串,適用于逐行讀取文件內(nèi)容,通常結(jié)合 sscanf 使用以進(jìn)一步解析數(shù)據(jù)。

  • fscanf: 按照格式說明符從文件中讀取數(shù)據(jù),適用于逐項(xiàng)解析數(shù)據(jù)。

6.綜合示例

示例:從文件中讀取并解析數(shù)據(jù)

假設(shè)有一個(gè)文本文件 students.txt,內(nèi)容如下:

John 20 85.5
Alice 22 90.0
Bob 21 78.5
#include <stdio.h>

int main() {
    FILE *file = fopen("students.txt", "r");
    if (file == NULL) {
        perror("無法打開文件");
        return 1;
    }

    char name[50];
    int age;
    float score;

    while (fscanf(file, "%s %d %f", name, &age, &score) == 3) {
        printf("姓名: %s, 年齡: %d, 分?jǐn)?shù): %.1f\n", name, age, score);
    }

    fclose(file);
    return 0;
}

輸出

姓名: John, 年齡: 20, 分?jǐn)?shù): 85.5
姓名: Alice, 年齡: 22, 分?jǐn)?shù): 90.0
姓名: Bob, 年齡: 21, 分?jǐn)?shù): 78.5

解釋:

  • fscanf 從文件 students.txt 中解析每一行數(shù)據(jù),并輸出到屏幕上。它通過格式說明符 %s %d %f 解析每行中的姓名、年齡和分?jǐn)?shù)。

完!

到此這篇關(guān)于c語言中比較特殊的輸入函數(shù)的文章就介紹到這了,更多相關(guān)c語言特殊輸入函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實(shí)現(xiàn)獲取文件MD5值

    C語言實(shí)現(xiàn)獲取文件MD5值

    MD5(Message?Digest?Algorithm?5)是一種常用的哈希函數(shù)算法,這篇文章主要介紹了C語言如何獲取文件MD5值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • C++控制臺實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲

    C++控制臺實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲

    這篇文章主要為大家詳細(xì)介紹了C++控制臺實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 深入解讀C++ 內(nèi)聯(lián)函數(shù)inline|nullptr

    深入解讀C++ 內(nèi)聯(lián)函數(shù)inline|nullptr

    內(nèi)聯(lián)函數(shù):用** inline 修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用的地方展開內(nèi)聯(lián)函數(shù)**,這樣調(diào)用內(nèi)聯(lián)函數(shù)就需要?jiǎng)?chuàng)建棧楨,就提高效率了,這篇文章給大家介紹C++ 內(nèi)聯(lián)函數(shù)inline|nullptr的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • C語言鏈表與單鏈表詳解

    C語言鏈表與單鏈表詳解

    鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的,本章帶你詳細(xì)了解鏈表與單鏈表
    2022-02-02
  • 使用c++11 constexpr時(shí)遇到的坑詳解

    使用c++11 constexpr時(shí)遇到的坑詳解

    c++11 constexpr將變量聲明為constexpr類型以便由編譯器來驗(yàn)證變量是否是一個(gè)常量表達(dá)式,這篇文章主要給大家介紹了關(guān)于使用c++11 constexpr時(shí)遇到的坑,需要的朋友可以參考下
    2021-05-05
  • C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解

    C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解

    這篇文章主要介紹了C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解,需要的朋友可以參考下
    2018-03-03
  • Qt基于QRencode實(shí)現(xiàn)生成二維碼

    Qt基于QRencode實(shí)現(xiàn)生成二維碼

    QRencode是一個(gè)開源的庫,專門用于生成二維碼(QR?Code),這篇文章主要為大家詳細(xì)介紹了Qt如何使用QRencode實(shí)現(xiàn)生成二維碼功能,需要的可以參考下
    2025-02-02
  • C++保存txt文件實(shí)現(xiàn)方法代碼實(shí)例

    C++保存txt文件實(shí)現(xiàn)方法代碼實(shí)例

    這篇文章主要介紹了C++保存txt文件實(shí)現(xiàn)方法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 聊聊c++數(shù)組名稱和sizeof的問題

    聊聊c++數(shù)組名稱和sizeof的問題

    這篇文章主要介紹了c++數(shù)組名稱和sizeof,介紹了一維數(shù)組名稱的用途及二維數(shù)組數(shù)組名,通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • C++通過共享內(nèi)存ShellCode實(shí)現(xiàn)跨進(jìn)程傳輸

    C++通過共享內(nèi)存ShellCode實(shí)現(xiàn)跨進(jìn)程傳輸

    在計(jì)算機(jī)安全領(lǐng)域,ShellCode是一段用于利用系統(tǒng)漏洞或執(zhí)行特定任務(wù)的機(jī)器碼,本文主要為大家介紹了C++如何通過共享內(nèi)存ShellCode實(shí)現(xiàn)跨進(jìn)程傳輸,需要的可以參考下
    2023-12-12

最新評論