sscanf解析CGI参数时忽略&符号,读取内容超出预期范围怎么办?
sscanf解析CGI查询字符串时读取超出预期内容
我把编译后的.cpp文件作为CGI文件运行,用来接收网页表单数据,用sscanf()解析提取数据时,第一个字符串变量读取了超出预期的全部后续内容。
我的CPP代码:
#include <stdio.h> #include <stdlib.h> #include <string> int main(void) { printf("Content-Type: text/plain;charset=us-ascii\n\n"); printf("Hello world\n\n"); char* data; data = getenv("QUERY_STRING"); char name [50]; int port; int id; char config[50]; sscanf(data, "Name=%s&Port=%d&ID=%d&Config=%s", &name, &port, &id, &config); printf("%s", name); return 0; }
已知data变量值为"Name=ss&Port=8081&ID=0&Config=testconfig":
- 预期输出:
Hello world ss
- 实际输出:
Hello world ss&Port=8081&ID=0&Config=testconfig
我尝试过把data和name改成std::string类型,但问题没解决,想知道为什么sscanf会忽略&符号,把所有数据存入该变量?
原因
sscanf的%s格式符默认会读取连续的非空白字符,直到遇到空白字符(空格、换行、制表符等)才停止。而&不属于空白字符,所以%s会从Name=后面开始,一直读到整个字符串的末尾,把ss&Port=8081&ID=0&Config=testconfig全部塞进name数组里。
解决方法
使用%[^&]格式符,它表示读取所有非&的字符,直到遇到&为止。同时为了避免缓冲区溢出(比如name数组是50字节),要加上长度限制,写成%49[^&](预留1字节给字符串终止符\0)。
修改后的sscanf语句:
sscanf(data, "Name=%49[^&]&Port=%d&ID=%d&Config=%49[^&]", name, &port, &id, config);
注意:name本身就是数组首地址,不需要加&,之前的&name写法虽然能运行,但不符合规范,应该直接写name。
额外注意事项
- 要判断
getenv("QUERY_STRING")的返回值是否为NULL,避免空指针访问:if (data == NULL) { printf("No query string provided"); return 1; } - 检查
sscanf的返回值,确保所有字段都解析成功:int result = sscanf(data, "Name=%49[^&]&Port=%d&ID=%d&Config=%49[^&]", name, &port, &id, config); if (result != 4) { printf("Failed to parse all fields"); return 1; }
内容的提问来源于stack exchange,提问作者stav
相关产品推荐
相关产品推荐

