【问题标题】:sscanf(str1, "%s %d %f", str2,&num,&float1) producing unexpected resultssscanf(str1, "%s %d %f", str2,&num,&float1) 产生意外结果
【发布时间】:2019-10-03 02:30:48
【问题描述】:

使用包含的库,如何将包含姓名、年龄和比率的字符串与存储在数组中的 fget 的输入分开?

我需要修改字符串、年龄和格式以显示 3 位小数。之后,我需要将这些变量的新结果存储在单个 char 数组中。这就是我到目前为止所拥有的。我不知道是什么导致 sscanf() 给我意外的结果或如何解决它

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

#define SIZE 10
#define SIZE2 40

int main(){
char input[SIZE2]={};
char name[SIZE]={};
int age = 0;
float rate = 0;

printf("Enter name, age and rate (exit to quit): ");
fgets(input, SIZE2, stdin);

sscanf(input,"%s %d %f", name, &age, &rate);

printf("%s %d %.3f",name, &age, &rate);

return 0;
}

名字显示正常,但是年龄是一个随机的大数,比率显示为0.000

【问题讨论】:

    标签: c input scanf


    【解决方案1】:

    去掉printf("%s %d %.3f",name, &age, &rate)中运算符(&)的地址像 printf("%s %d %.3f",姓名,年龄,率);

    当你把 & 运算符放在 printf() 中时,它会打印出变量的地址


    但为什么 scanf() 需要 & 运算符?

    让我们看一个例子:

    int main()
    {
     int *ad,var;
     ad=&var;
     *ad=10;
     printf("%d",var);
     return 0;
    }
    

    它将打印 10

    让我们看看另一个函数示例:

    void sum(int *sum,int a,int b)
    
    int main()
    {
     int a=10,b=10,c;
     sum(&c,a,b);
     printf("%d",c);
     return 0;
    } 
    
    void sum(int *sum,int a,int b)
    {
     *sum=a+b;
    }
    

    它将打印 20

    所以,如果你想修改函数中的变量,你可以通过引用传递变量

    所以,scanf()需要运算符的&来获取变量的地址

    【讨论】:

    • 谢谢。删除 printf 和我的 sprintf 中的 & 运算符修复了输出问题。似乎 sscanf() 工作正常。
    • 但是为什么 scanf() 需要 & 运算符?
    • ....因为它预计会修改变量..这些值是无用的 - 它必须有它们的地址,以便它可以使用新值加载变量。
    【解决方案2】:

    您需要检查 sscanf 的返回值,看它是否能够找到并解析您在格式字符串中指定的内容。您还应该限制提取到固定大小缓冲区中的字符串的大小,以免缓冲区溢出。所以你想要类似的东西

    while(true) {
        printf("Enter name, age and rate (exit to quit): ");
        if (fgets(input, sizeof(input), stdin) == 0) {
            // error or eof on the input
            exit(0); }
        if (sscanf(input,"%9s%d%f", name, &age, &rate) == 3)
            break;  // ok
        printf("I didn't understand that input\n");
    }
    printf("%s %d %.3f",name, age, rate);
    

    【讨论】:

    • 固定大小的缓冲区?为什么尺寸 40 (SIZE2) 会成为我的代码中的问题?
    • name 只有 10 个字节——如果输入的名称超过这个长度,缓冲区将会溢出。
    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多