2012-10-22 39 views
0

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

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("")));写的文件也许这是原因?

+0

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

+0

您希望L“30 237 740“返回30237740? – Spidey

回答

0

为什么不只是使用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。

+0

但为什么我的功能不起作用? – abilash

+0

你说过它可以与控制台(或“键盘”,无论你的意思是什么)的输入一起工作,不是吗?然后,如果它不适用于该文件,则它必须是该文件的编码不是Unicode。 – user1610015

+0

当我更改粘贴到IDE(进入函数参数)的空间到由我输入的空间(在此IDE中)它的工作原理。 – abilash

1

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

请尝试std::wcout << wchartol(L"30 237 740\r\n") << 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; 
    } 
} 

(声明:我没有测试此码,对自己的风险所以使用)

+0

我忘了说这个函数只用于已知结构的文件。它不包含任何转义序列。其中的数据有我以前写过的数据。我写过这个文件使用std :: wcout.imbue(std :: locale :: global(std :: locale(“”))),也许它有理由? – abilash

+0

您是否尝试过使用调试程序逐步执行程序?这是确保您的字符串看起来如预期的最佳方式。 – SvenS

+0

@StevenS我放弃了它,strArray的类型是L“30 237 740” – abilash

0

这个循环therfore是错误的

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

,因为你增加你测试之前,在字符串的开头不会被发现的空间。我假设你的意思是这个

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

在这种情况下,如果第一个字符不是空格,它仍然会被跳过。你的意思是把'firstArray ++'完全放在'if'之后。这意味着循环后的'firstArray - '也应该被删除。 – Shahbaz

+0

这并不是说在开始的时候空间不会被发现,而是他为空字符的计数加1,忽略第一个字符,不管它是什么。这里的解决方法是正确的。 – CashCow

+0

@john我使用它,但这没有帮助 – abilash