自定义可前移输入字符串指针的sscanf风格函数调用时出现无法读取内存错误求助
问题分析与修复方案
你的代码里存在几个关键问题,直接导致了内存访问错误,我们逐一拆解并修复:
1. 指针类型不匹配(最直接的崩溃原因)
在main函数中,你传递的是&inputStr,但inputStr是char[10]类型的数组,&inputStr的实际类型是指向长度为10的char数组的指针(char (*)[10]),而你的函数参数要求的是char **(指向char指针的指针)。这两种指针类型完全不兼容,强行传递会导致指针地址解析错误,直接触发内存访问异常。
解决方法:先把数组转换成char*类型,再传递它的地址:
char *ptr = inputStr; scanStrAndMove(&ptr, "%s", outputSrt);
2. 空格判断的指针访问错误
你的空格跳过逻辑里,isspace(*readString[forwardBy])写法错误。readString是char**,readString[forwardBy]会取第forwardBy个char*指针,而你实际想访问的是当前*readString指向的字符串的第forwardBy个字符,正确写法应该是:
while(isspace( (*readString)[forwardBy] ))
3. 错误的指针偏移计算逻辑
你用strlen(writeString) + strlen(formatString) - 2计算偏移量的方式完全不可靠:
- 如果
formatString包含修饰符(比如%10s),这种计算直接失效; - 如果
sscanf因为缓冲区大小限制截断了输入,strlen(writeString)会小于实际扫描的字符数; - 对于非字符串格式(比如
%d),这种方法根本不适用。
正确的做法是利用sscanf的%n格式符,它会记录到目前为止扫描过的字符总数,用这个值能准确计算偏移量。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> int scanStrAndMove(char **readString, const char* formatString, char *writeString){ int forwardBy = 0; // 跳过前置空格,同时避免访问字符串末尾外的内存 while((*readString)[forwardBy] != '\0' && isspace((*readString)[forwardBy])){ forwardBy++; } // 标记当前扫描的起始位置 char *start = *readString + forwardBy; int scanned = 0; // 用%n获取实际扫描的字符数 int retVal = sscanf(start, formatString "%n", writeString, &scanned); if(retVal > 0){ // 总偏移量:跳过的空格数 + 实际扫描的字符数 *readString += forwardBy + scanned; } return retVal; } int main(int argc, char *argv[]) { char inputStr[10] = " cde fg"; char outputSrt[10]; // 先将数组转为char指针,再传递地址 char *ptr = inputStr; scanStrAndMove(&ptr,"%s",outputSrt); printf("%s\n",outputSrt); // 输出cde scanStrAndMove(&ptr,"%s",outputSrt); printf("%s\n",outputSrt); // 输出fg return 0; }
修复说明
- 解决了指针类型不匹配的问题,避免了非法内存访问;
- 修正了空格判断的指针访问逻辑,确保正确跳过输入字符串的前置空格;
- 使用
%n格式符准确获取sscanf实际扫描的字符数,保证指针偏移量的正确性; - 增加了字符串末尾判断,防止越界访问。
内容的提问来源于stack exchange,提问作者omri nitzan
相关产品推荐
相关产品推荐

