C中的字符串输出

我们常接触的字符串输入函数有常见的gets() fgets() scanf("%s") 我们将分开介绍

0)什么是不检查边界?

  假如一个int数组申请了十个元素的空间,但是有些函数在输入的时候不会检查边界,如果输入超过10个元素,会直接越界修改后面的内存中的元素。

  可能会导致:缓冲区溢出攻击、程序崩溃、数据损坏。

1)gets()

  gets()不检查函数边界,在C11被废弃。会导致缓冲区溢出。他会一直读取到换行符,换行符已经被读取,但是并不存储(读取并丢弃)。会在字符串末尾添加'\0'。

 

image

 

image

 

 2)fgets()

  fgets()是最为推荐的函数,

#include <stdio.h>  // 必需的头文件
char *fgets(char *str, int n, FILE *stream);

image

   请注意,n是包含'\0'的。

image

  他的特点是:安全(不会从缓冲区溢出),读取整行(包括空格和换行符)。

#include <stdio.h>
#include <string.h>  // 用于字符串处理

int main() {
    char name[50];
    
    printf("请输入你的名字: ");
    fgets(name, sizeof(name), stdin);
    
    // 去掉换行符
    name[strcspn(name, "\n")] = '\0';
    
    printf("你好,%s!\n", name);
    
    return 0;
}
#include <stdio.h>
#include <string.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    char line[256];
    
    if (file == NULL) {
        printf("无法打开文件\n");
        return 1;
    }
    
    // 逐行读取文件
    while (fgets(line, sizeof(line), file) != NULL) {
        // 去掉换行符
        line[strcspn(line, "\n")] = '\0';
        printf("%s\n", line);
    }
    
    fclose(file);
    return 0;
}

  那么如何处理多读进来的换行符呢?以下是三种方式,建议第一种。

 

char str[100];
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0';  // 简洁高效
char str[100];
fgets(str, sizeof(str), stdin);

char *newline = strchr(str, '\n'); // 找第一个元素出现的地方
if (newline) {
    *newline = '\0';
}
char str[100];
fgets(str, sizeof(str), stdin);

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

  Windows和Linux换行符差异

// Windows: \r\n
// Linux: \n
// OJ通常是Linux环境

// 安全处理:同时去掉\r和\n
char *pos;
if ((pos = strchr(str, '\r')) != NULL) *pos = '\0';
if ((pos = strchr(str, '\n')) != NULL) *pos = '\0';

  fgets() 读取空行

// 用户直接按回车
fgets(str, sizeof(str), stdin);
// str的内容是: "\n\0"

// 处理:检查是否空行
if (str[0] == '\n') {
    printf("输入了空行\n");
    str[0] = '\0';  // 设为空字符串
}

   混合输入(数字+字符串)

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

int main() {
    int age;
    char name[50];
    
    printf("年龄: ");
    scanf("%d", &age);
    
    // 关键:清除输入缓冲区中的换行符
    while (getchar() != '\n');
    
    printf("姓名: ");
    fgets(name, sizeof(name), stdin);
    name[strcspn(name, "\n")] = '\0';
    
    printf("%s今年%d岁\n", name, age);
    
    return 0;
}

3)scanf("s");

  仍然不检查边界,可以通过“9s"来检查边界。

  • 遇到空白字符(空格、制表符、换行符)就停止

  • 不会读取空白字符,留它们在输入缓冲区
  • 在字符串末尾添加 \0

  所以需要我们用getchar()清除掉空白符。或用" %s"清除前导空白符。

posted @ 2026-01-02 14:05  Nowasiki  阅读(1)  评论(0)    收藏  举报