简体   繁体   中英

Convert function from wchar_t array to long int

I'm writing a function that converts a wchar_t array to long integer values (the function ignores spaces beetwen digits). Look at my code:

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;
}

I have another funny problem: when I copy digit data (it contains spaces) from some file and paste it into the function's argument, I get wrong data returned by the function; but when I replace these spaces with spaces typed in the keyboard, all works great. What's the reason? I invoke the function this way:

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

Reading a file written using outputstream.imbue(std::locale::global(std::locale(""))); Maybe that's the reason?

Your code assumes that the input string consists of digits and spaces only, terminated by null-character. It is possible that piping in a file will end the string with newline and then null. As a result you count '\\r' and '\\n' as digits, subtracting '0' from them and increasing the pow accordingly.

Please try std::wcout << wchartol(L"30 237 740\\r\\n") << std::endl; and see if it produces the same incorrect value.

Edit: Here is some code that doesn't make any assumptions about the string, it will just ignore any spaces when concatenating the first integer in the string, if there is one. It sets the pointer to the position just after the first char that is neither a digit nor a space and concatenates all digits from there to the start of the string:

// 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;
  }
}

(disclaimer: I didn't test this code, so use on own risk)

Why not just use wstringstream?

wifstream in(...);
wstringstream ss;

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

    in >> ch;
}

long number;
ss >> number;

As for the problem with the file, it might be that the file's encoding is not Unicode. Try opening the file with a text editor and telling it to store the file as Unicode.

This loop is wrong

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

since you increment before you test therfore a space at the start of the string won't be found. I assume you meant this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM