【问题标题】:sscanf Wildcard multi string %s not return first string rightly?sscanf 通配符多字符串 %s 不能正确返回第一个字符串?
【发布时间】:2020-06-01 15:38:37
【问题描述】:

我正在使用sscanf 来读取字符串。字符串被空格分割。 sscanf 不返回第一个字符串。 代码如下:

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

int main(int argc, char** argv) {
    char TransactionID[15], CardID[8];
    char Datetime[50];
    int Amount;
    char * s="aaaabbbbcccc defadbed 2020:04:29:23:07:00 1234";
    sscanf(s,"%s %s %s %d", TransactionID, CardID, Datetime, &Amount);
    printf("s[0] = %c\n", s[0]);
    printf("amount = %d\n", Amount);
    printf("TransactionID = %s\n", TransactionID);
    printf("CardID = %s\n", CardID);
    printf("Datetime = %s\n", Datetime);
    return 0;
}

输出是:

s[0] = a
amount = 1234
TransactionID =
CardID = defadbed
Datetime = 2020:04:29:23:07:00

TransactionID 没有返回正确的结果。但是其他的都对。

【问题讨论】:

  • CardID 的长度不足以存储 NUL 终止符。因此,您的代码可能只是具有未定义的行为。
  • @underscore_d 也许。
  • 我很慷慨。确实如此。
  • 也检查来自sscanf 的返回值。 if(sscanf(...) != 4) {...}
  • @WeatherVane,它返回 4。

标签: c string scanf


【解决方案1】:

您的代码中有缓冲区溢出:CardID 只有 8 个字节长。虽然输入字符串中的卡 ID 为 8 个字符,但结尾的 NUL 字节还需要另一个字节。将CardID 的声明更改为:

char TransactionID[15], CardID[9];

应该修复解析这个特定的输入字符串。

但是,如果输入有错误,或者有人恶意为您提供的卡 ID 比您的代码预期的要长,您仍然会遇到问题。因此,您应该确保永远不会发生缓冲区溢出。

一种方法是告诉scanf() 每个缓冲区有多大,如下所示:

sscanf(s,"%14s %7s %49s %d", TransactionID, CardID, Datetime, &Amount);

请注意,您必须再次指定比缓冲区大小小一。所以如果要处理 8 个字符的卡 ID,仍然需要将缓冲区大小设置为 9 个字节。然而,虽然这可以防止缓冲区溢出,但如果输入字符串大于缓冲区,其余的将被静默截断,或者下一次 %s 转换可能会拾取剩余的字符。

如果您知道输入由空格分隔,那么另一种方法是使用strtok() 将输入拆分为各个部分。

【讨论】:

  • 应该是%8s
猜你喜欢
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多