sscanf 通配符多字符串 %s 不是 return 第一个字符串对吗?
sscanf Wildcard multi string %s not return first string rightly?
我正在使用 sscanf
来读取字符串。字符串被 space 分割。 sscanf
不是 return 第一个字符串。
代码如下:
#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 不是 return 正确的结果。不过其他都对。
您的代码中存在缓冲区溢出: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 个字节。然而,虽然这可以防止缓冲区溢出,但如果输入字符串大于缓冲区,其余的将被静默 t运行 处理,或者下一个 %s
转换可能会选择剩余的字符。
如果您知道输入是由空格分隔的,那么另一种方法是使用 strtok()
将输入拆分为各个部分。
我正在使用 sscanf
来读取字符串。字符串被 space 分割。 sscanf
不是 return 第一个字符串。
代码如下:
#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 不是 return 正确的结果。不过其他都对。
您的代码中存在缓冲区溢出: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 个字节。然而,虽然这可以防止缓冲区溢出,但如果输入字符串大于缓冲区,其余的将被静默 t运行 处理,或者下一个 %s
转换可能会选择剩余的字符。
如果您知道输入是由空格分隔的,那么另一种方法是使用 strtok()
将输入拆分为各个部分。