2009-11-27 35 views
1

我在解析函數時遇到了一些麻煩,所以我放了一些cout語句告訴我運行時某些變量的值,並且我相信atoi不正確地轉換字符。我錯誤地使用atoi嗎?

繼承人我的一小段程式碼,多數民衆贊成舉止怪異:

c = data_file.get(); 
if (data_index == 50) 
    cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl; 

輸出的這種說法是: 50 digit 0 = '5' number = 52

我打電話一個循環內的代碼,並且什麼奇怪的是,它正確地轉換了前47個字符,然後在第48個字符後它在整數後面加了一個0,在第49個字符上它增加了一個1,在第50個(見這裏)它增加了一個2,一直到第57個字符它增加了一個9,然後它繼續正確地轉換到第239個字符。

這是奇怪的還是什麼?

只是澄清一點點我會發布整個功能。這個函數會得到一個指向空雙陣列(ping_data):

int parse_ping_data(double* ping_data) 
{ 
    ifstream data_file(DATA_FILE); 

    int pulled_digits [4]; 
    int add_data; 
    int loop_count; 
    int data_index = 0; 

    for (char c = data_file.get(); !data_file.eof(); c = data_file.get()) 
    { 
     if (c == 't' && data_file.get() == 'i' && data_file.get() == 'm' && data_file.get() == 'e' && data_file.get() == '=') 
     { 
      loop_count = 0; 
      c = data_file.get(); 
      if (data_index == 50) 
        cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl; 
      pulled_digits[loop_count] = atoi(&c); 

      while ((c = data_file.get()) != 'm') 
      { 
       loop_count++; 
       if (data_index == 50) 
        cout << "50 digit " << loop_count << " = '" << c << "' number = " << atoi(&c) << endl; 
       pulled_digits[loop_count] = atoi(&c); 
      } 
      add_data = 0; 
      for (int i = 0; i <= loop_count; i++) 
       add_data += pulled_digits[loop_count - i] * (int)pow(10.0,i); 

      if (data_index == 50) 
       cout << "50 index = " << add_data << endl; 
      ping_data[data_index] = add_data; 
      data_index++; 

      if (data_index >= MAX_PING_DATA) 
      { 
       cout << "Error parsing data. Exceeded maximum allocated memory for ping data." << endl; 
       return MAX_PING_DATA; 
      } 
     } 
    } 

    data_file.close(); 

    return data_index; 
} 

回答

6

atoi接受一個字符串,即char S,而不是指向一個單一char一個空值終止陣列,所以這是不正確的,會得到你無法預料的結果。

char c; 
//... 
/* ... */ atoi(&c) /* ... */ 

此外,atoi不提供任何方法來檢測錯誤,所以寧願strtol和類似的功能。

E.g.

char *endptr; 
char c[2] = {0}; // initalize c to all zero 

c[0] = data.file.get(); // c[1] is the null terminator 

long l = strtol(c, &endptr, 10); 

if (endptr == c) 
    // an error occured 
2

沒關係,它只是我需要將字符轉換爲以\ 0結尾的字符串。我把它改爲這個代碼:

char buffer [2];

buffer [1] ='\ 0';

buffer [0] = data_file.get();

如果(data_index用於== 50)

cout << "50 digit 0 = '" << buffer[0] << "' number = " << atoi(buffer) << endl; 

和它的工作。

+1

太棒了,但是當你使用atoi來回目的時,你還在用大炮射擊麻雀。 – AnT 2009-11-28 03:25:18

3

atoi需要以空字符結尾的字符串作爲輸入。你所提供的不是以空字符結尾的字符串。

話雖如此,值得一提的是,要正確使用atoi非常困難(如果可能的話)。 atoi是一種不提供錯誤控制和無溢出控制的功能。在C標準庫中執行字符串表示到數字轉換的唯一正確方法是從strto...組開始的函數。

其實,如果你只需要轉換一個字符數字,使用atoi或其他任何字符串轉換函數是一個奇怪的矯枉過正。正如已經提出的那樣,您只需從字符數字值中減去0的值即可獲得相應的數值。語言規範保證這是一個便攜式解決方案。