作者penril0326 ()
看板C_and_CPP
標題[問題] C語言實作atoi
時間Thu Nov 13 01:02:44 2014
各位大大好,小弟最近在練程式實作atoi這個function
卻發生一個問題我怎麼想都不知道錯在哪
atoi是把一個字串轉成int型態
我的錯誤是如果我的字串是 char s[]="-123";
結果輸出會是-122,也就是說我目前唯一發現有問題的地方是
只要輸入是"負號且3位數",結果就會少1
(ex:-987變成-986)
非3位數跟正整數就不會有這問題
叫朋友幫我編譯他說他沒問題
但我自己的電腦跟學校電腦都會這樣
想請版上高手幫我解答,我使用的編譯器是code::blocks
以下是code
int Myatoi(char* s)
{
int sum=0,i=0,count1=0;
int j,lenght,count2;
lenght = strlen(s);
if (s[0] != '-')
{
if (s[0] < '0' && s[0] > '9')
{
return 0;
}
else
{
while (s[i] >= '0' && s[i] <= '9')
{
count1++;
i++;
}
count2 = count1 - 1;
for (j=0;j<count1;j++)
{
sum = sum + ((int)(s[j] - '0')) * pow(10,count2);
count2--;
}
return sum;
}
}
else
{
while (s[i+1] >= '0' && s[i+1] <='9')
{
count1++;
i++;
}
count2 = count1 - 1;
for (j=0;j<count1;j++)
{
sum = sum + ((int)(s[j+1] - '0')) * pow(10,count2);
count2--;
}
sum = 0 - sum;
return sum;
}
}
先感謝各位~
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.43.100.199
※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1415811768.A.065.html
推 KoenigseggG: 你可以加入一些printf看看哪裡出錯了 11/13 01:21
→ KoenigseggG: 是說 if (s[0] < '0' && s[0] > '9') 這不會true吧 11/13 01:24
→ KoenigseggG: 當然啦~學習用 debugger 很重要。 11/13 01:25
假設字串是a123應該就會true了吧?
推 LPH66: 我覺得問題是在 pow(10,count2) 上, 這是浮點數函數所以 11/13 01:36
→ LPH66: 不保證回傳回來的浮點數會正好整數, 在轉成 int 時截掉小數 11/13 01:37
→ LPH66: 就造成誤差了;其實你可以不用 pow 來寫的 11/13 01:38
→ LPH66: 提示: 想想怎麼從 12 和 3 算出 123 來 11/13 01:38
→ carylorrk: 讓我想到有人說,學習一個語言的 debug 方式才能說你學 11/13 02:02
→ carylorrk: 過這個語言XD 11/13 02:02
→ PoorLoser: 1. pow() 回傳 float 11/13 02:18
→ PoorLoser: 2. int * float 會轉型成 float * float 11/13 02:19
→ PoorLoser: 3. pow() 指數浮點運算有精度問題, 可能回傳 999.99... 11/13 02:20
→ PoorLoser: 4. 假設輸入 456, 可能得到 455.9999XX... ... 11/13 02:21
→ PoorLoser: 5. 再轉型成 int, 捨棄小數就少了 1 11/13 02:22
→ PoorLoser: 不過正整數沒問題就有點怪 11/13 02:25
各位高手們好,我其實在上來問之前已經用printf檢查過,在負整數的時候
比如-123,它在做1*10^2次方時就變成99了,可是我不知道變成99的理由,
因為正整數沒這問題,所以我剛剛去下載devC來跑,結果就正確了@_@
現在大概只能推測是編譯器的問題,不知道這兩個編譯器之間有什麼差異??
另外我會想想LPH大大的方法~
※ 編輯: penril0326 (114.43.100.199), 11/13/2014 02:37:46
※ 編輯: penril0326 (114.43.100.199), 11/13/2014 02:39:46
推 phishingphi: 什麼時候code::blocks是編譯器... 11/13 02:57
推 phishingphi: devC這個...應該不妥吧, code應該有問題. 11/13 03:00
好啦,其實就講久了就自然而然把它當成編譯器來講,phi大講的應該是什麼
GNU GCC之類的吧?我其實沒有很了解那些.....還請大大指教
另外我自己也真的不是喜歡用devC,因為有過傷痛...(汗)
※ 編輯: penril0326 (114.43.100.199), 11/13/2014 03:32:51
→ Caesar08: 我想給個建議,你可以先把-從字串裡面移除,這樣你就不 11/13 05:45
→ Caesar08: 用寫2段一模一樣的code 11/13 05:46
那這樣我該怎麼判斷負數呢?
推 KoenigseggG: 他想說c::b是IDE吧。其實我昨晚用你code測-123是對的 11/13 07:35
→ KoenigseggG: (gcc 4.8.1), float pow()這我沒注意到艸 11/13 07:37
→ KoenigseggG: 我還是認為不會true啊~雖然問題應該不在這0.0 11/13 07:43
→ KoenigseggG: 讓我想到大一考試,同一份code, c::b跑出TA給的答案 11/13 07:44
→ KoenigseggG: 工作站(linux)直接Segmentation fault...... 11/13 07:46
→ KoenigseggG: 從此拋棄c::b(?) 11/13 07:47
推 KoenigseggG: 是說為啥跟下面那篇都會想用pow()做啊0.0需求是轉int 11/13 07:53
→ KoenigseggG: 就像LPH大大說的那樣 11/13 07:54
想問一下K大用哪個IDE?我後來用C::B跟DevC兩個去跑,DevC的結果是正確的
想知道原因為何?
另外你說我不會true那邊的想法是如果char s[]="a123"; 一開始a不等於-
所以會進去,然後a的ASCII是97,所以這時候就會true然後return 0
不知道這樣想有沒有錯;然後我後來把pow()改掉結果就正確了,不過我還是不知道用LPH
大的方法怎麼做QQ,還請大大給點提示><
→ dirkc: 的確pow,strlen都不需要,另外原始atoi()可以處理前綴空白 11/13 09:22
→ dirkc: atoi也有考慮INT_MAX/INT_MIN; 不過簡化難度來練習也不錯:) 11/13 09:26
strlen我後來沒用到,忘記拿掉而已XD
※ 編輯: penril0326 (140.118.126.159), 11/13/2014 17:37:30
推 KoenigseggG: '0' -> 48, '9' -> 57. 不會 97 < 48 && 97 > 57. 11/13 22:01
→ KoenigseggG: 還是我哪裡錯艸。我用vim+gcc喔~我也不知為何會這樣 11/13 22:02
→ KoenigseggG: LPH大大應該是說 12 * 10 + 3 = 123? 11/13 22:03
阿我知道錯在哪了XDDD應該用or才對哈哈,我一直以為我是寫or才會覺得我會對XD
我常常會沒發現這些小地方然後想破頭不知道錯在哪,曾經因為分號忘記打然後
還用printf找超久.....
我也想過那個方法,本來想說應該沒這麼簡單吧(艸
※ 編輯: penril0326 (114.25.40.14), 11/13/2014 22:35:44
※ 編輯: penril0326 (114.25.40.14), 11/13/2014 22:37:37
→ KoenigseggG: 嗯,害我每次推文前都再查一次表XD 11/13 23:56
→ KoenigseggG: 說不定真的沒這麼簡單@@因為那是我的作法,我猜的 11/13 23:57
→ dirkc: 如樓上所說,if/while就可以做了,沒什麼高深的語法 11/14 09:08
推 Jimmy0301: 其實判斷空白可以用 isspace,判斷是否為數字 isdigit 11/17 23:56