不能在 C 中将 sscanf() 用于 char 数组

Posted

技术标签:

【中文标题】不能在 C 中将 sscanf() 用于 char 数组【英文标题】:can't use sscanf() in C for char array 【发布时间】:2020-07-17 21:33:16 【问题描述】:

我试图获得一个非常大的数字(超过unsigned long long int)。所以我把它作为一个字符串,然后将它逐位转换为整数并使用它。

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

int main() 
 
    char m[100];
    int x;
    scanf("%s",m);
    for(int i=0; i<strlen(m); i++)
        sscanf(m[i],"%d",&x);
        printf("%d",x);
    

    return 0; 

但是,在编译过程中显示:

警告:传递“sscanf”的参数 1 使指针变为整数 没有演员表

注意:预期为“const char * restrict”,但参数的类型为“char”

而且,当我运行程序时,它会给我Segmentation fault (core dumped) 错误。

我也尝试了更简单的代码来查找问题:

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

int main() 
 
    char m[5];
    char n;
    int x;
    scanf("%s",m);
    n = m[1];
    sscanf(n,"%d",&x);  
    return 0; 

但没有任何改变。

【问题讨论】:

%d 不是“数字”,而是“有符号十进制整数”。但至于错误本身,sscanf 需要一个 const char *(即一个字符串),但你只给出了一个字符。 m 只有四个字符加上一个谢谢,“非常长”是一个令人震惊的误称。对于很长的数字字符串,您不能安全地使用%d;溢出的行为是未定义的。 sscanf(m[i],"%d",&amp;x); 是错误的。你应该改用x = m[i] - '0';。并且您的输入字符串对于大数字来说太小了。 【参考方案1】:

scanf 不适用于字符。获得字符后,只需将 '0' 作为字符减去即可将数字转换为整数:

for(int i=0; i<strlen(m); i++)
    x = m[i] - '0';   // line to change
    printf("%d",x);

此外,为了确保缓冲区不会溢出,100 字节是好的,但您可能希望在scanf 中使用相应的限制并检查返回码:

if (scanf("%99s",m) == 1) 

【讨论】:

【参考方案2】:

使用sscanf 将字符串的个位转换为整数是错误的方法。为此,您只需从该数字中减去字符 '0' 的表示形式的(整数)值。像这样:

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

int main()

    char m[50]; // As pointed out, a 4-digit number isn't really very long, so let's make it bigger
    int x;
    scanf("%49s", m); // Limit the input to the length of the buffer!
    for (size_t i = 0; i < strlen(m); i++)  // The "strlen" function return "size_t"
        x = m[i] - '0'; // The characters `0` thru `9` are GUARANTEED to be sequential!
        printf("%d", x);
    
    return 0;

【讨论】:

【参考方案3】:

scanf 不适用于字符。获得字符后,只需将 '0' 作为字符减去即可将数字转换为整数:

for(int i = 0; i < strlen(m); i++) 
    x = m[i] - '0';  
    printf("%d", x);

【讨论】:

以上是关于不能在 C 中将 sscanf() 用于 char 数组的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在发布版本中将 char* 字符串从 C++ 返回到 C#?

是否可以在 C 中使用 sscanf 在 shell 中创建别名命令?

为啥我不能在c中将字符串转换为int

在c中将长动态字符串拆分为字符串数组

sscanf 导致地址越界

sscanf 导致地址越界