最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

一.getchar()函數(shù)

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

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("請(qǐng)輸入一個(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("請(qǐng)輸入一行文字,按回車結(jié)束: ");
    
    while ((ch = getchar()) != '\n' && ch != EOF) {
        printf("讀取字符: %c\n", ch);
    }
    
    printf("輸入結(jié)束。\n");
    
    return 0;
}

解釋:

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

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

#include <stdio.h>

int main() {
    int ch;

    printf("請(qǐng)輸入字符,輸入結(jié)束請(qǐng)按 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é)束符(通常是在控制臺(tái)輸入時(shí)按下Ctrl+DCtrl+Z),getchar()將返回常量EOF,其值通常為-1。EOF用于指示輸入的結(jié)束或錯(cuò)誤情況。

4.應(yīng)用場(chǎng)景

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

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

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

5.注意事項(xiàng)

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

  • 緩沖區(qū)問(wèn)題: 在控制臺(tái)輸入時(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語(yǔ)言中用于從文件流中讀取一行字符串的標(biāo)準(zhǔn)庫(kù)函數(shù)。它提供了一種安全、方便的方法來(lái)讀取輸入,避免了諸如緩沖區(qū)溢出等常見問(wèn)題。fgets 通常用于讀取用戶輸入、從文件中讀取數(shù)據(jù)等場(chǎng)景。

1.函數(shù)原型

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

  • str: 指向字符數(shù)組的指針,fgets 會(huì)將讀取到的字符串存儲(chǔ)在該數(shù)組中。
  • n: 要讀取的最大字符數(shù),包括結(jié)尾的空字符 \0。也就是說(shuō),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: 如果在讀取過(guò)程中遇到文件末尾,讀取操作結(jié)束。

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

3.使用示例

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

#include <stdio.h>

int main() {
    char buffer[100];

    printf("請(qǐng)輸入一行文本:");
    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("無(wú)法打開文件");
        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.處理?yè)Q行符

正如前面提到的,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';
}

解釋:

  • 首先獲取字符串的長(zhǎng)度 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(wú)法指定讀取的最大長(zhǎng)度,容易導(dǎo)致緩沖區(qū)溢出。

  • fgets: 可以指定最大讀取長(zhǎng)度,安全性更高。建議始終使用 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: 一次讀取一行或指定長(zhǎng)度的字符串,效率更高。

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). 未正確處理?yè)Q行符

如前所述,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ū)大小與讀取長(zhǎng)度匹配

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

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

char buffer1[50], buffer2[50];

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

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

如果在第一次輸入時(shí)輸入的字符超過(guò)了 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("請(qǐng)輸入您的姓名:");
    if (fgets(name, sizeof(name), stdin) != NULL) {
        // 去除換行符
        name[strcspn(name, "\n")] = '\0';
    } else {
        printf("讀取姓名失敗。\n");
        return 1;
    }

    // 讀取年齡
    printf("請(qǐng)輸入您的年齡:");
    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語(yǔ)言中用于從字符串中讀取并解析數(shù)據(jù)的標(biāo)準(zhǔn)庫(kù)函數(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ù)格式。它的語(yǔ)法和 scanf 的格式字符串相同,包括各種格式說(shuō)明符(如 %d%s%f 等)。
  • ...: 可變參數(shù)列表,提供用于存儲(chǔ)從字符串中讀取的數(shù)據(jù)的指針。

返回值

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

2.工作原理

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

格式說(shuō)明符示例

  • %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)容多于格式說(shuō)明符指定的內(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)容與格式說(shuō)明符不匹配,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 還可以使用 * 來(lái)忽略某些輸入數(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ù)返回值來(lái)驗(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ù)

如果輸入字符串的格式與格式說(shuō)明符不匹配,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ū)有足夠的空間以避免溢出。使用長(zhǎng)度限制格式符號(hào)(如 %99s)可以防止緩沖區(qū)溢出。

(4). 處理多余輸入

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

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ù)。%[^,] 格式說(shuō)明符用于讀取直到遇到逗號(hào) , 的所有字符,這樣可以處理包含空格的姓名。

四.fscanf()函數(shù)

fscanf 是C語(yǔ)言中用于從文件讀取并解析數(shù)據(jù)的標(biāo)準(zhǔn)庫(kù)函數(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ù)說(shuō)明

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

返回值

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

2.工作原理

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

格式說(shuō)明符示例

  • %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("無(wú)法打開文件");
        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 通常按格式說(shuō)明符讀取數(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("無(wú)法打開文件");
        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。這可以用來(lái)判斷是否已經(jīng)讀取到文件末尾。

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

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

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

#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("無(wú)法打開文件");
        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ù)返回值來(lái)驗(yàn)證解析操作的成功與否。

示例:檢查返回值

#include <stdio.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    if (file == NULL) {
        perror("無(wú)法打開文件");
        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)容多于格式說(shuō)明符指定的內(nèi)容,fscanf 只會(huì)處理指定的部分,忽略其余部分。

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

(1). 格式不匹配

如果文件中的內(nèi)容與格式說(shuō)明符不匹配,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: 按照格式說(shuō)明符從文件中讀取數(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("無(wú)法打開文件");
        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ù),并輸出到屏幕上。它通過(guò)格式說(shuō)明符 %s %d %f 解析每行中的姓名、年齡和分?jǐn)?shù)。

完!

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

相關(guān)文章

  • C++實(shí)現(xiàn)動(dòng)態(tài)綁定代碼分享

    C++實(shí)現(xiàn)動(dòng)態(tài)綁定代碼分享

    對(duì)于C++動(dòng)態(tài)綁定的理解,就是編譯器用靜態(tài)分析的方法加上虛擬函數(shù)的設(shè)計(jì)實(shí)現(xiàn)在程序運(yùn)行時(shí)動(dòng)態(tài)智能執(zhí)行正確虛擬函數(shù)的技術(shù)。要徹底理解動(dòng)態(tài)綁定,只需要掌握兩點(diǎn),一是編譯器的靜態(tài)編譯過(guò)程,二是虛擬函數(shù)的基本知識(shí)。只要有了這兩點(diǎn)理解,任何動(dòng)態(tài)綁定的分析都是很容易的
    2015-11-11
  • C語(yǔ)言:代碼宏詳解

    C語(yǔ)言:代碼宏詳解

    這篇文章主要介紹了 C語(yǔ)言宏定義使用實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-09-09
  • C++中CSTRINGLIST用法詳解

    C++中CSTRINGLIST用法詳解

    這篇文章主要介紹了C++中CSTRINGLIST用法詳解的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • C語(yǔ)言全部?jī)?nèi)存操作函數(shù)的實(shí)現(xiàn)詳細(xì)講解

    C語(yǔ)言全部?jī)?nèi)存操作函數(shù)的實(shí)現(xiàn)詳細(xì)講解

    這篇文章主要介紹了C語(yǔ)言全部?jī)?nèi)存操作函數(shù)的實(shí)現(xiàn)詳細(xì)講解,作者用圖文代碼實(shí)例講解的很清晰,有感興趣的同學(xué)可以研究下
    2021-02-02
  • Qt實(shí)現(xiàn)驗(yàn)證碼相關(guān)功能的代碼示例

    Qt實(shí)現(xiàn)驗(yàn)證碼相關(guān)功能的代碼示例

    驗(yàn)證碼的原理基于人類視覺和計(jì)算機(jī)視覺的差異性,通過(guò)給用戶顯示一些難以被機(jī)器識(shí)別的圖形或文字,讓用戶進(jìn)行人機(jī)交互,確認(rèn)自己的身份,這樣可以有效保護(hù)網(wǎng)站安全,所以本給大家介紹了Qt實(shí)現(xiàn)驗(yàn)證碼相關(guān)功能的代碼示例,感興趣的朋友可以參考下
    2024-01-01
  • C++中static和const的作用和用法

    C++中static和const的作用和用法

    在C++中,"static"和"const"都是用于修飾變量的關(guān)鍵字,它們具有不同的作用,本文通過(guò)代碼示例給大家詳細(xì)的介紹static和const的作用和用法,,需要的朋友可以參考下
    2023-06-06
  • C語(yǔ)言實(shí)現(xiàn)學(xué)生選修課程系統(tǒng)設(shè)計(jì)

    C語(yǔ)言實(shí)現(xiàn)學(xué)生選修課程系統(tǒng)設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生選修課程系統(tǒng)設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • 基于OpenCV自定義色條實(shí)現(xiàn)灰度圖上色功能代碼

    基于OpenCV自定義色條實(shí)現(xiàn)灰度圖上色功能代碼

    今天通過(guò)本文給大家分享基于OpenCV自定義色條實(shí)現(xiàn)灰度圖上色功能代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)飛機(jī)票務(wù)系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)飛機(jī)票務(wù)系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)飛機(jī)票務(wù)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘

    Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07

最新評(píng)論

扶绥县| 陆良县| 华容县| 广州市| 高要市| 台南县| 海兴县| 叶城县| 西林县| 新闻| 噶尔县| 探索| 孟村| 汤阴县| 台州市| 庆安县| 无为县| 桐庐县| 常山县| 怀安县| 香港 | 凌海市| 霍林郭勒市| 游戏| 同江市| 镶黄旗| 余姚市| 永兴县| 吴川市| 家居| 麦盖提县| 石楼县| 子长县| 连城县| 安康市| 怀仁县| 醴陵市| 泸定县| 文化| 连山| 亚东县|