2009-09-28 24 views
2

我发现使用strtol将十六进制字符串转换为signed int的代码,但我找不到短int(2字节)的内容。这里的代码我的作品:将带前导“0x”的十六进制字符串转换为C++中的带符号短符号?

while (!sCurrentFile.eof()) 
{ 
    getline (sCurrentFile,currentString); 
    sOutputFile<<strtol(currentString.c_str(),NULL,16)<<endl; 
} 

我的想法是读取文件用2个字节宽值(如0xFFEE),将其转换为符号的int和输出文件中写入结果。执行速度不是问题。

我能找到一些方法来避免这个问题,但我想用“一条线”的解决方案,所以也许你可以帮助这个:)

编辑:文件看起来是这样的:

0x0400 
0x03fe 
0x03fe 
... 

编辑:我已经尝试过使用十六进制运算符,但我仍然必须将字符串转换为整数,然后才能这样做。

// This won't work as currentString is not an integer 
myInt << std::hex << currentString.c_str(); 
+0

什么是您的输入文件是什么样子?没有这些信息就很难提出任何建议。 – hrnt 2009-09-28 14:53:04

+0

请参阅strtol返回long,未签名int, – Satbir 2009-09-28 14:54:59

+0

sscanf返回int,但scanf-family函数的返回值是它们成功转换的字段数。虽然我很欣赏这个宣传,但是你错了。 :) – ChrisV 2009-09-28 17:50:19

回答

3

您是否认为sscanf带有“%hx”转换限定符?

+0

或者,如果您没有特别需要使用C++ I/O流,请直接访问fscanf ...取决于您控制的代码的多少。 – ChrisV 2009-09-28 15:10:59

+0

fscanf和sscanf是我通常如何处理这个问题的。我有一个程序,现在读取与此类似的CRC十六进制字符串: sscanf(cstr_fileCRC,“%lX”,&ul_fileCRC); – 2009-09-28 15:59:31

+0

这个问题被标记为C++。另外,'sscanf'通常会因为它带来的与安全有关的问题而被忽视。 – jww 2017-05-07 04:46:22

3

您可以使用stringtream类的>>操作符与十六进制操纵器。

+0

正是我所需要的,它只是一大行! – gramm 2009-09-28 15:43:58

+0

你应该提供一个例子。前导'0x'似乎会导致解析失败。 – jww 2017-05-07 04:47:22

-1

如果你确定的数据可以从currentString.c_str()被信任,那么你可以很容易地也做

myInt << std::hex << atoi(currentString.c_str()); 
+1

为什么使用C函数的时候,C++流代码完成所有工作。 – 2009-09-28 16:51:30

+0

这个问题被标记为C++,而不是C. – jww 2017-05-07 04:47:55

-1

如果你知道数据总是要在该格式,不能你只是做是这样的:

myInt << std::hex << currentString.c_str() +2; // skip the leading "0x" 
+0

在这里,std :: hex在处理字符串时不做任何事情。您只是重新打印您读取的字符串(减去前两个字符)。 – 2009-09-28 16:50:48

3

这应该是简单的:

std::ifstream file("DataFile"); 
int    value; 

while(file >> std::hex >> value) // Reads a hex string and converts it to an int. 
{ 
    std::cout << "Value: " << std::hex << value << "\n"; 
} 

虽然我们TAL关于文件的国王:
你应该做到这一点:

while (!sCurrentFile.eof()) 
{ 
    getline (sCurrentFile,currentString); 
    ... STUFF ... 
} 

这是因为当你读到最后一行它设置EOF。所以,当你循环并在最后一行之后读取行时,getline()将会失败,并且你将在上次创建时在currentString中做什么。因此,您将最后一行处理两次。

正确地遍历文件是:

while (getline(sCurrentFile,currentString)) 
{ 
    // If the get fails then you have read past EOF and loop is not entered. 
    ... STUFF ... 
} 
0
// convert unsigned-integer to it's hexadecimal string represention 
// 0x12345678 -> '12345678' 
// N is BYTE/WORD/UINT/ULONGLONG 
// T is char or wchar_t 
template <class N, class T> inline T* UnsignedToHexStr(N n    , // [i ] 
                 T* pcStr   , // [i/o] filled with string 
                 UINT nDigits  , // [i ] number of digits in output string/0 (auto) 
                 bool bNullTerminate) // [i ] whether to add NULL termination 
{ 
    if ((N)-1 < (N)1)    // if type of N is floating-point/signed-integer 
     if (::IsDebuggerPresent()) 
     { 
      ::OutputDebugString(_T("UnsignedToHexStr: Incorrect type passed\n")); 
      ::DebugBreak(); 
     } 

    if (!nDigits) 
     nDigits= GetUnsignedHexDigits(n); 

    if (1 == sizeof(T)) 
    { 
     const char _czIntHexConv[]= "ABCDEF"; 
     for (int i= nDigits-1; i>= 0; i--) 
     { 
      char* pLoc= (char*)&pcStr[i]; 
      *pLoc= _czIntHexConv[n & 0x0F]; 
      n >>= 4; 
     } 
    } 
    else 
    { 
     const wchar_t _czIntHexConv[]= L"ABCDEF"; 
     for (int i= nDigits-1; i>= 0; i--) 
     { 
      wchar_t* pLoc= (wchar_t*)&pcStr[i]; 
      *pLoc= _czIntHexConv[n & 0x0F]; 
      n >>= 4; 
     } 
    } 

    if (bNullTerminate) 
     pcStr[nDigits]= 0; 

    return pcStr; 
} 



// -------------------------------------------------------------------------- 
// convert unsigned-integer in HEX string represention to it's numerical value 
// '1234' -> 0x1234 
// N is BYTE/WORD/UINT/ULONGLONG 
// T is char or wchar_t 
template <class N, class T> inline bool HexStrToUnsigned(const T* pczSrc     , 
                 N&  n       , 
                 bool  bSpecificTerminator= false, // whether string should terminate with specific terminating char 
                 T  cTerminator  = 0 ) // specific terminating char 
{ 
    n= 0; 

    if (!pczSrc) 
     return false; 

    while ((32 == *pczSrc) || (9 == *pczSrc)) 
     pczSrc++; 

    bool bLeadZeros= *pczSrc == _T('0'); 
    while (*pczSrc == _T('0')) // skip leading zeros 
     pczSrc++; 

    BYTE nMaxDigits= 2*sizeof(N); 
    BYTE nDigits = 0   ; 

    while (true) 
    { 
     if ((*pczSrc >= _T('0')) && (*pczSrc <= _T('9'))) 
     { if (nDigits==nMaxDigits) return false; n= (n<<4) + (*pczSrc-_T('0') ); pczSrc++; nDigits++; continue; } 

     if ((*pczSrc >= _T('A')) && (*pczSrc <= _T('F'))) 
     { if (nDigits==nMaxDigits) return false; n= (n<<4) + (*pczSrc-_T('A')+10); pczSrc++; nDigits++; continue; } 

     if ((*pczSrc >= _T('a')) && (*pczSrc <= _T('f'))) 
     { if (nDigits==nMaxDigits) return false; n= (n<<4) + (*pczSrc-_T('a')+10); pczSrc++; nDigits++; continue; } 

     if (bSpecificTerminator) 
      if (*pczSrc != cTerminator) 
       return false; 

     break; 
    } 

    return (nDigits>0) || bLeadZeros; // at least one digit 
} 
+0

你显然很生气:-) – 2009-09-28 18:25:52

相关问题