当前位置: 首页 > article >正文

VS2022的MFC的ReadString的问题

用vs2022CStdioFile类读取文件时,当文件中出现有一段0,不是字符串0而是16进制0,会导致直接读取结束,但实际文件还有很长,则后面的内容无法读入。
因为之前用过vc6的同样的函数ReadString进行读取是没有问题的。因此问题肯定出现在这个函数上。
将VS2022的ReadString的函数拷贝出如下:

BOOL CStdioFile::ReadString(CString& rString)
{
ASSERT_VALID(this);
rString = _T("");    // empty string without deallocating
const int nMaxSize = 128;
LPTSTR lpsz = rString.GetBuffer(nMaxSize);
LPTSTR lpszResult;
int nLen = 0;
for (;;)
{
    lpszResult = _fgetts(lpsz, nMaxSize+1, m_pStream);
    rString.ReleaseBuffer();

    // handle error/eof case
    if (lpszResult == NULL && !feof(m_pStream))
    {
        Afx_clearerr_s(m_pStream);
        AfxThrowFileException(CFileException::genericException, _doserrno,
            m_strFileName);
    }

    // if string is read completely or EOF
    if (lpszResult == NULL ||
        (nLen = AtlStrLen(lpsz)) < nMaxSize ||
        lpsz[nLen-1] == '\n')
        break;

    nLen = rString.GetLength();
    lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
}

// remove '\n' from end of string if present
lpsz = rString.GetBuffer(0);
nLen = rString.GetLength();
if (nLen != 0 && lpsz[nLen-1] == '\n')
    rString.GetBufferSetLength(nLen-1);

return nLen != 0;

}

代码来源:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\atlmfc\src\mfc\filetxt.cpp

VC6的对应函数源码:

BOOL CStdioFile::ReadString(CString& rString)
{
ASSERT_VALID(this);
rString = &afxChNil;    // empty string without deallocating
const int nMaxSize = 128;
LPTSTR lpsz = rString.GetBuffer(nMaxSize);
LPTSTR lpszResult;
int nLen = 0;
for (;;)
{
    lpszResult = _fgetts(lpsz, nMaxSize+1, m_pStream);
    rString.ReleaseBuffer();

    // handle error/eof case
    if (lpszResult == NULL && !feof(m_pStream))
    {
        clearerr(m_pStream);
        AfxThrowFileException(CFileException::generic, _doserrno,
            m_strFileName);
    }

    // if string is read completely or EOF
    if (lpszResult == NULL ||
        (nLen = lstrlen(lpsz)) < nMaxSize ||
        lpsz[nLen-1] == '\n')
        break;

    nLen = rString.GetLength();
    lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
}

// remove '\n' from end of string if present
lpsz = rString.GetBuffer(0);
nLen = rString.GetLength();
if (nLen != 0 && lpsz[nLen-1] == '\n')
    rString.GetBufferSetLength(nLen-1);

return lpszResult != NULL;

}

经过对比,可以发现
原来最后的判断不同了,VS2022是判断指针是否为0(return lpszResult != NULL;),VC6是判断字符串长度是否为0(return nLen != 0;)

若是正常的文本,中间不会出现二进制0的。
但在处理异常情况下,VC6的函数就要优一些,至于为何VS2022的函数要这样修改,我还没有搞明白。
但现在我要处理的文件中有16进制0,文件又需要全部读完,用VS2022的函数就行。退回用VC6又不现实。
最后解决办法是,继承CStdioFile类,重写ReadString函数,或增加一个ReadString函数(改个名)。使用的函数内容从VC6的MFC源码中进行拷贝。问题得到解决。


http://www.kler.cn/a/413063.html

相关文章:

  • 关闭AWS账号后,服务是否仍会继续运行?
  • gRPC 双向流(Bidirectional Streaming RPC)的使用方法
  • shell中的EOF,字符块
  • 英语知识网站:Spring Boot技术构建
  • 【软件介绍】变声工具RVC本地部署使用方法
  • Docker部署mysql:8.0.31+dbsyncer
  • 熔断限流:业务实现自我保护
  • C++ ADL参数依赖查找
  • scala统计词频
  • 嵌入式工程师面试笔试总结——day2
  • TorchMoji使用教程/环境配置(2024)
  • 记录下在html文件中如何直接使用npm依赖,以threejs为例
  • sentry前端接入 报错403
  • 2022 年 3 月青少年软编等考 C 语言三级真题解析
  • YourPHPCMS Register_checkEmail存在sql注入漏洞
  • uniapp中的事件:v-on
  • Spring Boot 3 集成 Spring Security(3)数据管理
  • 同时多平台git配置:GitHub和Gitee生成不同的SSH Key
  • WPF——自定义ToolTip
  • Git远程仓库过大导致clone失败的解决方法
  • pytorch 和tensorflow loss.item()` 只能用于只有一个元素的张量. 防止显存爆炸
  • 什么是缓存击穿?如何避免之布隆过滤器
  • 07 初始 Oracle 优化器
  • Java设计模式笔记(一)
  • 14、保存与加载PyTorch训练的模型和超参数
  • PyTorch:神经网络的基本骨架 nn.Module的使用