You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何读取含空格字符串?fgets函数参数用法解析

fgets 函数用法说明(重点解释第三个参数)

fgets 的函数原型为 char *fgets(char *str, int n, FILE *stream);,三个参数的含义和传值要求如下:

  • 第一个参数:存储读取内容的字符数组首地址,和你用 scanf 读字符串时传入的数组名作用一致
  • 第二个参数:最大读取字符数,注意 fgets 会自动在读取内容末尾补 \0 作为字符串结束标记,因此实际最多读取 n-1 个有效字符,传值时直接传入目标字符数组的定义长度即可,比如你定义 char nome_resp[50],这里就传 50,从根源避免数组越界
  • 第三个参数:输入流指针,用来指定读取内容的来源。如果要读取键盘敲入的内容,直接传 C 标准库预置的标准输入流 stdin 即可;如果是读取本地文件内容,就传 fopen 打开文件后返回的文件指针。

你现有代码的典型问题

你目前混用 scanf 和自定义 %[^\n]s 格式串读取带空格字符串,会触发几个常见的C语言输入坑:

  1. scanf 读取完输入后,会把你敲回车产生的 \n 换行符残留在输入缓冲区里,下一次用 %[^\n] 或者 fgets 读取时,会直接读到这个残留换行,表现为程序直接跳过某一步输入,不让你敲内容
  2. %[^\n]s 格式串没有限制读取长度,输入过长时会直接写爆字符数组,造成内存溢出,而fgets自带长度限制,天然规避这个问题
  3. 你代码里打印 CPF 时用了 %s 格式符,但 cpf_resp/cpf_edu 定义为int类型,会直接打印乱码;且11位的CPF号码超过了普通int的存储范围(普通int最多存10位十进制数),用字符数组存储更合理,既不会溢出,也能保留号码前导0。

修正后的可运行参考代码

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

void funcCadastroDados();
// 工具函数:清空scanf残留在输入缓冲区的换行符
void clearInputBuffer() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main(){
    setlocale(LC_ALL, "Portuguese");
    funcCadastroDados();
    return 0;
}

void funcCadastroDados(){
    system("cls");
    char tipo_usuario[20], nome_resp[50], nome_crianca[50], transtorno_crianca[50], email_resp[50], nome_edu[50], nome_crianca_associada[50], email_edu[50];
    // CPF、电话号码长度超过int存储范围,改用字符数组存储
    char cpf_resp[15], tel_resp[15], cpf_edu[15], tel_edu[15];
    printf("Você é pai/responsável da criança ou educador? \nDigite 'responsavel' ou 'educador' \n");
    scanf("%s", tipo_usuario);
    clearInputBuffer();

    if ((strcmp(tipo_usuario, "responsavel")) == 0){
        printf("Insira o nome do responsável: \n");
        fgets(nome_resp, 50, stdin);
        // fgets会把输入末尾的换行符也读入数组,手动替换为字符串结束符
        nome_resp[strcspn(nome_resp, "\n")] = '\0';

        printf("Insira o CPF do responsável: \n");
        scanf("%s", cpf_resp);
        clearInputBuffer();

        printf("Insira o nome da criança: \n");
        fgets(nome_crianca, 50, stdin);
        nome_crianca[strcspn(nome_crianca, "\n")] = '\0';

        printf("Insira o transtorno mental que a criança possui: \n");
        fgets(transtorno_crianca, 50, stdin);
        transtorno_crianca[strcspn(transtorno_crianca, "\n")] = '\0';

        printf("Insira o telefone do responsável: \n");
        scanf("%s", tel_resp);
        clearInputBuffer();

        printf("Insira o email do responsável: \n");
        scanf("%s", email_resp);
        clearInputBuffer();
        
        printf("\nSeus dados são: \n Nome do responsável: %s \n CPF do responsável: %s \n Nome da criança: %s \n Transtorno mental: %s \n "
        "Telefone do responsável: %s \n Email do responsável: %s \n", nome_resp, cpf_resp, nome_crianca, transtorno_crianca, tel_resp, email_resp);
    }
    else if ((strcmp(tipo_usuario, "educador")) == 0){
        printf("Insira o nome do educador: \n");
        fgets(nome_edu, 50, stdin);
        nome_edu[strcspn(nome_edu, "\n")] = '\0';

        printf("Insira o CPF do educador: \n");
        scanf("%s", cpf_edu);
        clearInputBuffer();

        printf("Insira o nome da criança associada a este educador: \n");
        fgets(nome_crianca_associada, 50, stdin);
        nome_crianca_associada[strcspn(nome_crianca_associada, "\n")] = '\0';

        printf("Insira o telefone do educador: \n");
        scanf("%s", tel_edu);
        clearInputBuffer();

        printf("Insira o email do educador: \n");
        scanf("%s", email_edu);
        clearInputBuffer();

        printf("\nSeus dados são: \n Nome do educador: %s \n CPF do educador: %s \n Nome da criança associada: %s \n Telefone do educador: %s \n"
        "Email do educador: %s \n", nome_edu, cpf_edu, nome_crianca_associada, tel_edu, email_edu);
    }
}

fgets 使用注意点

  • 读取键盘输入时第三个参数固定传 stdin 即可,不需要额外定义
  • 每次用fgets读完内容后,记得把读入的末尾换行符替换为 \0,否则打印字符串时会多出不必要的空行
  • 第二个参数永远不要超过目标字符数组的实际定义长度,否则会触发数组越界bug

内容的提问来源于stack exchange,提问作者arthursleite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:39:26