本人在做文件属性的时候,发现一个奇怪的问题:CString sStr;CFile::GetStatus(fileStatus); 获取一个文件的属性。。sStr.Format(_T("文件大小: %d字节 (%d字节)"),fileStatus.m_size,fileStatus.m_size);根据获取到的属性来格式化字符串。。假设fileStatus.m_size = 200;现在根据这个获取的结果 居然是:文件大小 200字节 (0字节)不知道为啥,第一可以获取到数值,第二就不能哪?? fileStatus.m_size 的类型是 ULONGLONG      typedef unsigned __int64 ULONGLONG; sStr.Format(_T("文件大小: %d字节 (%d字节)"),fileStatus.m_size,(int)fileStatus.m_size); //强制转换还是不行。。ULONGLONG nSize = fileStatus.m_size;sStr.Format(_T("文件大小: %d字节 (%d字节)"),nSize,nSize);用一个变量来代替还是不行求高人来解决下。。谢谢!!不知道为啥会有这样的结果

解决方案 »

  1.   

    改成这样试试:sStr.Format(_T("文件大小: %I64u字节 (%I64u字节)"),nSize,nSize);
      

  2.   

    http://msdn.microsoft.com/en-us/library/tcxf1dw6(VS.71).aspx
      

  3.   

    根本就不是第二次取不到,你这样的话:         ULONGLONG A=10;
    ULONGLONG B=10; sStr.Format(_T("文件大小: %d字节 (%d字节)"),A,B);
    AfxMessageBox(sStr);也是一样显示“文件大小 10字节 (0字节)”
      

  4.   

    是否括号引起的,试试这样:CString sStr;
    CString sStr2;CFile::GetStatus(fileStatus); 获取一个文件的属性。。sStr.Format(_T("文件大小: %d字节 "),fileStatus.m_size);sStr2.Format(_T(%d字节"),fileStatus.m_size);sStr=sStr+"("+sStr2+")";
      

  5.   

    sStr=sStr+"("+sStr2+")";  ->sStr+=_T("("+sStr2+")");
      

  6.   


    format把传进去的参数当做int类型,缺省参数的format函数其取的第二个参数时,实际上取到的是第一个数的高4字节为0这样就好了
    sStr.Format(_T("文件大小: %d字节 (%d字节)"),(int)fileStatus.m_size,(int)fileStatus.m_size);
      

  7.   

    研究了一下,你用%d格式化的时候,它把ULONGLONG当成了两个int类型来处理了;
    所以你程序中输出的其实是ULONGLONG的低4个字节和高4个字节你看看下面的代码
    CString sStr;
    ULONGLONG A=10;
    ULONGLONG B=10; sStr.Format(_T("文件大小: %d %d字节 (%d %d字节)"),A,B);
    AfxMessageBox(sStr);输出的是“文件大小 10 0字节 (10 0字节)”有兴趣的话,你可以单步进CString::Format里面看看
      

  8.   

    你可以这样测试下
      ULONGLONG ulTest1=0x6fffffff7fffffff;
      ULONGLONG ulTest2=0x8888888888;
      
      CString  sStr;
      sStr.Format(_T("文件大小: %x字节 (%x字节)"),ulTest1, ulTest2);
      

  9.   

    你可以单步进CString::Format里面看看这个怎么单步进去这个函数里面。。F11 直接就过去了!!这些系统函数单步进不去吧??请教方法
      

  10.   

    你先设个断点在sStr.Format上
    运行到这里时,按F11就能进去啊
      

  11.   


     这样打印 6fffffff ,7fffffff 其实打印的只是ulTest1的值。看到了只是高位和地位的值ulTest2的值根本没打印。。Str.Format(_T("文件大小: %x字节 (%x字节) %x %x"),ulTest1,ulTest2);
    这样书写,可以打印出来:
    Str = "文件大小: 7fffffff字节 (6fffffff字节) 88888888 88"
      

  12.   

    CString的Format操作的是一段内存Buffer,ULONGLONG A=10;ULONGLONG B=10;两个都是64位,但是在
    sStr.Format(_T("文件大小: %d字节 (%d字节)"),A,B)中使用的是%d,int在VS2008中是32位。两个%d加起来才64位,也就是说只用了A的64位的内存空间,而A的值是10,其他位都0,这样出来的结果就是:10(10);如果你把A的值改为:A=18446744073709551615; ULONGLONG b=11;,那么出来的结果就是:-1(-1)。改成%u话的就是4294967295(4294967295)
      

  13.   


    设置options->directory->source file 添加相应的“....\MFC\SRC”
      

  14.   

    出现这样的问题,主要还是字节类型转化的问题,因为你本来第一个是ULONGLONG型的数据,强制转化为int型在其转化后的数据长度不够,而你第二个数据就使用第一个数据的部分位置,因此就出现了这种情况。所以你是用强制转化也有提如:
    fileStatus.m_size 的类型是 ULONGLONG typedef unsigned __int64 ULONGLONG;  sStr.Format(_T("文件大小: %d字节 (%d字节)"),fileStatus.m_size,(int)fileStatus.m_size); //强制转换还是不行。。
    但是你这样就没问题
    sStr.Format((_T("文件大小:%I64u字节 (%d字节)"),fileStatus.m_size,fileStatus.m_size)
    了。关键还是第一个参数,而不是第二个
      

  15.   

    guangyou
     
    (冰城) 等 级: 根据以上大侠的解释,现在明白了。。64和32在取值时的差别。。以前都是取32的值,更不没遇到这样的问题。。(关键还是第一个参数,而不是第二个) 这个还是有问题,如果文件很大。。那二个取值还不是取大高位的值
    把64位的给截取了!!
    sStr.Format((_T("文件大小:%I64u字节 (%I64u字节)"),fileStatus.m_size,fileStatus.m_size)
    还是这样比较规范!!这样取就正确了!!
      

  16.   

    这个我还没去跟踪调试过,不过据我猜测是由于不定参数引起的。其实所谓的不定参数是用第一个参数来决定后续参数的个数的,而后续参数的大小参考是以int对齐的,也就是堆栈的每一个参数的大小,当用ULONGLONG时应该是push了两次,所以
    sStr.Format(_T("文件大小: %d字节 (%d字节)"),fileStatus.m_size,fileStatus.m_size);
    实际上的堆栈结构应该如下:
    fileStatus.m_size(高32bit)
    fileStatus.m_size(低32bit)
    fileStatus.m_size(高32bit)
    fileStatus.m_size(低32bit)
    "文件大小: %d字节 (%d字节)"地址所以出来的Format参数以字串作为参数个数参考,认为有两个参数,%d认为是两个int类型。
    (实际传入格式化函数的参数个数可以多于第一个参数指示的个数,但不能少于,少于会破坏堆栈)所以这样结果就肯定是
    文件大小 200字节 (0字节)