scanf 和 printf ; sscanf 和 sprintf ; fscanf 和 fprintf 的区别

scanfprintfsscanfsprintffscanffprintf 是 C 语言中用于输入和输出操作的标准库函数,它们之间有一些明显的区别,主要体现在它们处理输入/输出的源/目标上。

1. scanfprintf

  • scanf:从标准输入(通常是键盘)读取格式化的输入。
  • printf:将格式化的输出发送到标准输出(通常是屏幕)。

2. sscanfsprintf

  • sscanf:从字符串中读取格式化的输入。它允许你从一个已存在的字符串中解析出各种类型的数据。
  • sprintf:将格式化的输出发送到字符串。它允许你构建字符串,其中包含各种类型的数据。

3. fscanffprintf

  • fscanf:从文件中读取格式化的输入。它允许你从文件中读取数据。
  • fprintf:将格式化的输出发送到文件。它允许你将数据写入文件。

共同点与区别

  • 所有这些函数都使用格式字符串来指定如何读取或写入数据。
  • 它们的命名约定遵循相同的模式:xscanf 用于读取,xprintf 用于写入,其中 x 指示源或目标(如 s 代表字符串,f 代表文件)。
  • 它们的参数列表都是可变的,具体取决于格式字符串中指定的参数数量和类型。
  • 它们的返回值都提供了关于操作成功程度的信息(例如,读取或写入的项数)。

示例

scanf 和 printf
int num;
printf("Enter a number: ");
scanf("%d", &num);
printf("You entered: %d\n", num);
sscanf 和 sprintf
char input[] = "123";
int num;
sscanf(input, "%d", &num);
printf("Parsed number: %d\n", num);

char output[20];
sprintf(output, "The number is %d", num);
printf("Formatted string: %s\n", output);
fscanf 和 fprintf
FILE *file = fopen("data.txt", "w+"); // 打开文件以读写
if (file != NULL) {
    int num = 123;
    fprintf(file, "The number is %d\n", num); // 写入文件
    
    rewind(file); // 将文件指针移回文件开头
    
    int parsed_num;
    fscanf(file, "%d", &parsed_num); // 从文件读取
    printf("Read number from file: %d\n", parsed_num);
    
    fclose(file); // 关闭文件
}

在使用这些函数时,请始终检查返回值以确保操作成功,并考虑缓冲区溢出和其他潜在的错误情况。


使用 sscanf 的例子

   sscanf 是 C 语言中的一个标准库函数,用于从字符串中读取格式化输入。它的工作方式类似于 scanf,但是 scanf 是从标准输入(通常是键盘)读取数据,而 sscanf 是从一个字符串中读取数据。

函数的原型如下:

int sscanf(const char *str, const char *format, ...);
  • str:这是一个指向输入字符串的指针。
  • format:这是一个格式字符串,它指定了如何解释 str 中的数据。这个字符串中的格式说明符与 scanf 函数中的相同。
  • ...:这是一个可变参数列表,它取决于 format 字符串中指定的参数数量和类型。

sscanf 返回成功读取并赋值的变量数。如果到达字符串的末尾或者发生一个读取错误,则读取会停止。

以下是一个使用 sscanf 的例子:

#include <stdio.h>

int main() {
    char input[] = "Hello, 123, World!";
    char name[20];
    int number;

    // 使用 sscanf 从 input 字符串中读取数据
    if (sscanf(input, "Hello, %d, %19s!", &number, name) == 2) {
        printf("Number: %d, Name: %s\n", number, name);
    } else {
        printf("Failed to parse input\n");
    }

    return 0;
}

注意:在这个例子中,我们试图读取一个整数和一个字符串,但是字符串的顺序和 input 字符串中的实际顺序相反。这是因为 %d 对应于整数,而 %19s(注意 19 是为了防止缓冲区溢出)对应于字符串。此外,我们还使用了 %*s 的格式说明符(在这个例子中并未使用,但它是 sscanf 中的一个常用技巧)来跳过不需要读取的字符串部分。

运行上述代码会输出:

Number: 123, Name: World!

但是请注意,这个例子并不是很好的实践,因为它假设了输入字符串的格式。在实际应用中,你应该始终检查 sscanf 的返回值以确保你读取了正确数量的变量,并且你应该使用更健壮的方法来解析字符串(例如使用正则表达式或自定义解析器)。


使用 sprintf 的例子

  sprintf 是 C 语言中的另一个标准库函数,用于将格式化的数据写入一个字符串。与 sscanf 相反,sprintf 是将数据格式化为字符串,而不是从字符串中读取数据。

函数的原型如下:

int sprintf(char *str, const char *format, ...);
  • str:这是一个指向将要写入数据的字符串的指针。通常,这个字符串应该足够大以容纳格式化的结果和终止的空字符(\0)。
  • format:这是一个格式字符串,它指定了如何将数据格式化为字符串。这个字符串中的格式说明符与 printf 函数中的相同。
  • ...:这是一个可变参数列表,它取决于 format 字符串中指定的参数数量和类型。

sprintf 返回写入的字符数(不包括终止的空字符)。如果字符串缓冲区太小,无法容纳整个格式化的结果,则会发生缓冲区溢出,这是一个严重的安全问题。因此,通常建议使用 snprintf,它允许你指定一个最大字符数来防止缓冲区溢出。

以下是一个使用 sprintf 的例子,它模仿了之前 sscanf 例子中的数据格式:

#include <stdio.h>

int main() {
    char output[50]; // 确保输出缓冲区足够大
    int number = 123;
    char name[] = "World!";

    // 使用 sprintf 将数据格式化为字符串
    sprintf(output, "Hello, %d, %s!", number, name);

    // 打印生成的字符串
    printf("Generated string: %s\n", output);

    return 0;
}

运行上述代码会输出:

Generated string: Hello, 123, World!

请注意,在这个例子中,我们使用了 sprintf 来将整数 number 和字符串 name 格式化为一个字符串,并将结果存储在 output 数组中。然后,我们使用 printf 来打印这个生成的字符串。

由于 sprintf 可能会导致缓冲区溢出,因此在实际应用中,更推荐使用 snprintf,如下所示:

snprintf(output, sizeof(output), "Hello, %d, %s!", number, name);

这里,sizeof(output) 提供了 output 数组的大小(以字节为单位),但 snprintf 会将其转换为字符数(减去一个用于空字符的空间)来防止溢出。

  • 24
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值