【问题标题】:Convert function from wchar_t array to long int将函数从 wchar_t 数组转换为 long int
【发布时间】:2012-10-12 05:00:34
【问题描述】:

我正在编写一个将 wchar_t 数组转换为 long integer 值的函数(该函数忽略空格 beetwen 数字)。看我的代码:

long wchartol(wchar_t *strArray, long retVal = 0) {
  wchar_t *firstArray = strArray;
  long pow;
  int count, i;
  count = 0;
  i = 0;
  pow = 1;
  while(*firstArray != L'\0') {
    //firstArray++;
    if(*firstArray++ == L' ')continue;
    count++;
  }
  firstArray--;
  while(i < count) {
    if(*firstArray != L' ') {
      retVal += (*firstArray - L'0') * pow;
      pow*=10;
      i++;
    }
    firstArray--;
  }
  return retVal;
}

我还有一个有趣的问题:当我从某个文件中复制数字数据(它包含空格)并将其粘贴到函数的参数中时,我得到了函数返回的错误数据;但是当我用键盘输入的空格替换这些空格时,一切都很好。什么原因?我这样调用函数:

std::wcout << wchartol(L"30 237 740") << std::endl;

读取使用outputstream.imbue(std::locale::global(std::locale(""))); 编写的文件也许就是这个原因?

【问题讨论】:

  • 也许您输入的文件不包含宽字符。 (或者它会自动转换吗?我不这么认为......)请检查 wchartol("30 237 740") 是否返回相同的错误值,如果是这样,这显然是问题所在。此外,文件中的字符串可能包含换行符,当您遇到除空格以外的任何非数字字符时应停止处理(在 while(*firstArrax != L'\0') 行中)
  • 您希望 L"30 237 740" 返回 30237740?

标签: c++ c unicode encoding


【解决方案1】:

您的代码假定输入字符串仅由数字和空格组成,并以空字符结尾。文件中的管道可能会以换行符结束字符串,然后为空。因此,您将 '\r' 和 '\n' 视为数字,从中减去 '0' 并相应地增加 pow。

请尝试std::wcout &lt;&lt; wchartol(L"30 237 740\r\n") &lt;&lt; std::endl;,看看它是否会产生相同的错误值。

编辑:这是一些不对字符串做任何假设的代码,它只会在连接字符串中的第一个整数时忽略任何空格(如果有的话)。 它将指针设置到第一个既不是数字也不是空格的字符之后的位置,并将从那里的所有数字连接到字符串的开头:

// move pointer to position after last character to be processed
while( (*firstArray >= L'0' && *firstArray <= L'9')* ||
        *firstArray == L' ')
  firstArray++;

// process all digits until start of string is reached
while(firstArray > strArray) {
  firstArray--;
  if(*firstArray >= L'0' && *firstArray <= L'9') {
    retVal += (*firstArray - L'0') * pow;
    pow*=10;
  }
}

(免责声明:我没有测试此代码,因此使用风险自负)

【讨论】:

  • 我忘了说这个函数只用于已知结构的文件。它不包含任何转义序列。它文件中的数据有我以前写过的数据。我已经使用 std::wcout.imbue(std::locale::global(std::locale(""))); 写了这个文件,也许它有原因?
  • 您是否尝试过使用调试器单步执行您的程序?这是确保您的字符串看起来符合您预期的最佳方式。
  • @StevenS 我已经调试过了,strArray 的类型是 L"30 237 740"
【解决方案2】:

这个循环是错误的

while(*firstArray != L'\0')
{
    firstArray++;
    if(*firstArray == L' ')continue;
    count++;
}

因为你在测试之前递增,所以不会在字符串的开头找到空格。我猜你的意思是这个

while(*firstArray != L'\0')
{
    if(*firstArray++ == L' ')continue;
    count++;
}

【讨论】:

  • 这种情况下,如果第一个字符不是空格,仍然会被跳过。您的意思是将firstArray++ 完全放在if 之后。这意味着循环之后的firstArray--也应该被删除。
  • 不是找不到开头的空格,而是他对空字符的计数加1,不管第一个字符是什么,都忽略了。这里的修复是正确的。
  • @john 我用它,但这没有帮助
【解决方案3】:

为什么不直接使用 wstringstream?

wifstream in(...);
wstringstream ss;

wchar_t ch;
in >> ch;
while (in)
{
    if (ch != L' ')
        ss << ch;

    in >> ch;
}

long number;
ss >> number;

至于文件的问题,可能是文件的编码不是Unicode。尝试使用文本编辑器打开文件并告诉它以 Unicode 格式存储文件。

【讨论】:

  • 您说它确实适用于来自控制台(或来自“键盘”,无论您的意思是什么)的输入,不是吗?那么如果它对文件不起作用,那一定是文件的编码不是Unicode。
  • 当我将粘贴到 IDE(到函数参数)的空间更改为我输入的空间(到这个 IDE)时,它可以工作。
  • 好的,仍然。文件的编码不是 Unicode。尝试按照我的描述进行更改。你在使用 Windows 吗?如果是这样,请使用记事本打开文件并转到 文件 -> 另存为...。然后,在对话框的底部,将 Encoding 设置为 Unicode。
  • 不是 ANSI,但我已经使用 outputstream.imbue(std::locale::global(std::locale(""))); 写入 tjis 文件
猜你喜欢
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
相关资源
最近更新 更多