You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:52:56