[問題] C語言實作atoi

看板C_and_CPP作者時間9年前 (2014/11/13 01:02), 9年前編輯推噓9(9030)
留言39則, 8人參與, 最新討論串1/1
各位大大好,小弟最近在練程式實作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

11/13 01:21, , 1F
你可以加入一些printf看看哪裡出錯了
11/13 01:21, 1F

11/13 01:24, , 2F
是說 if (s[0] < '0' && s[0] > '9') 這不會true吧
11/13 01:24, 2F

11/13 01:25, , 3F
當然啦~學習用 debugger 很重要。
11/13 01:25, 3F
假設字串是a123應該就會true了吧?

11/13 01:36, , 4F
我覺得問題是在 pow(10,count2) 上, 這是浮點數函數所以
11/13 01:36, 4F

11/13 01:37, , 5F
不保證回傳回來的浮點數會正好整數, 在轉成 int 時截掉小數
11/13 01:37, 5F

11/13 01:38, , 6F
就造成誤差了;其實你可以不用 pow 來寫的
11/13 01:38, 6F

11/13 01:38, , 7F
提示: 想想怎麼從 12 和 3 算出 123 來
11/13 01:38, 7F

11/13 02:02, , 8F
讓我想到有人說,學習一個語言的 debug 方式才能說你學
11/13 02:02, 8F

11/13 02:02, , 9F
過這個語言XD
11/13 02:02, 9F

11/13 02:18, , 10F
1. pow() 回傳 float
11/13 02:18, 10F

11/13 02:19, , 11F
2. int * float 會轉型成 float * float
11/13 02:19, 11F

11/13 02:20, , 12F
3. pow() 指數浮點運算有精度問題, 可能回傳 999.99...
11/13 02:20, 12F

11/13 02:21, , 13F
4. 假設輸入 456, 可能得到 455.9999XX... ...
11/13 02:21, 13F

11/13 02:22, , 14F
5. 再轉型成 int, 捨棄小數就少了 1
11/13 02:22, 14F

11/13 02:25, , 15F
不過正整數沒問題就有點怪
11/13 02:25, 15F
各位高手們好,我其實在上來問之前已經用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

11/13 02:57, , 16F
什麼時候code::blocks是編譯器...
11/13 02:57, 16F

11/13 03:00, , 17F
devC這個...應該不妥吧, code應該有問題.
11/13 03:00, 17F
好啦,其實就講久了就自然而然把它當成編譯器來講,phi大講的應該是什麼 GNU GCC之類的吧?我其實沒有很了解那些.....還請大大指教 另外我自己也真的不是喜歡用devC,因為有過傷痛...(汗) ※ 編輯: penril0326 (114.43.100.199), 11/13/2014 03:32:51

11/13 05:45, , 18F
我想給個建議,你可以先把-從字串裡面移除,這樣你就不
11/13 05:45, 18F

11/13 05:46, , 19F
用寫2段一模一樣的code
11/13 05:46, 19F
那這樣我該怎麼判斷負數呢?

11/13 07:35, , 20F
他想說c::b是IDE吧。其實我昨晚用你code測-123是對的
11/13 07:35, 20F

11/13 07:37, , 21F
(gcc 4.8.1), float pow()這我沒注意到艸
11/13 07:37, 21F

11/13 07:43, , 22F
我還是認為不會true啊~雖然問題應該不在這0.0
11/13 07:43, 22F

11/13 07:44, , 23F
讓我想到大一考試,同一份code, c::b跑出TA給的答案
11/13 07:44, 23F

11/13 07:46, , 24F
工作站(linux)直接Segmentation fault......
11/13 07:46, 24F

11/13 07:47, , 25F
從此拋棄c::b(?)
11/13 07:47, 25F

11/13 07:53, , 26F
是說為啥跟下面那篇都會想用pow()做啊0.0需求是轉int
11/13 07:53, 26F

11/13 07:54, , 27F
就像LPH大大說的那樣
11/13 07:54, 27F
想問一下K大用哪個IDE?我後來用C::B跟DevC兩個去跑,DevC的結果是正確的 想知道原因為何? 另外你說我不會true那邊的想法是如果char s[]="a123"; 一開始a不等於- 所以會進去,然後a的ASCII是97,所以這時候就會true然後return 0 不知道這樣想有沒有錯;然後我後來把pow()改掉結果就正確了,不過我還是不知道用LPH 大的方法怎麼做QQ,還請大大給點提示><

11/13 09:22, , 28F
的確pow,strlen都不需要,另外原始atoi()可以處理前綴空白
11/13 09:22, 28F

11/13 09:26, , 29F
atoi也有考慮INT_MAX/INT_MIN; 不過簡化難度來練習也不錯:)
11/13 09:26, 29F
strlen我後來沒用到,忘記拿掉而已XD ※ 編輯: penril0326 (140.118.126.159), 11/13/2014 17:37:30

11/13 22:01, , 30F
'0' -> 48, '9' -> 57. 不會 97 < 48 && 97 > 57.
11/13 22:01, 30F

11/13 22:02, , 31F
還是我哪裡錯艸。我用vim+gcc喔~我也不知為何會這樣
11/13 22:02, 31F

11/13 22:03, , 32F
LPH大大應該是說 12 * 10 + 3 = 123?
11/13 22:03, 32F
阿我知道錯在哪了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

11/13 23:56, , 33F
嗯,害我每次推文前都再查一次表XD
11/13 23:56, 33F

11/13 23:57, , 34F
說不定真的沒這麼簡單@@因為那是我的作法,我猜的
11/13 23:57, 34F

11/14 09:08, , 35F
如樓上所說,if/while就可以做了,沒什麼高深的語法
11/14 09:08, 35F

11/15 00:31, , 36F
我也練了一下程式: http://codepad.org/UKkxXYIf
11/15 00:31, 36F

11/15 01:05, , 37F
overflow的部份沒寫好orz: http://codepad.org/rkHHKucn
11/15 01:05, 37F

11/17 23:56, , 38F
其實判斷空白可以用 isspace,判斷是否為數字 isdigit
11/17 23:56, 38F

11/18 00:25, , 39F
這我寫的但不一定對http://codepad.org/T4bO1QeU
11/18 00:25, 39F
文章代碼(AID): #1KOvAu1b (C_and_CPP)