2014-01-14 68 views
0

我有此線從一個txt文件(第一行中的文件中)採取:如何從字符串中提取整數? C++

#operation=1(create circle and add to picture) name X Y radius. 

爲什麼這種代碼犯規取整數1,並把它分成k?

Circle Circle::CreateCirc(Circle c){ 
    int k; 
    ifstream myfile("cmd.txt"); 
    if (!myfile.is_open()) 
     cout<<"Unable to open the requested file "<<endl; 
    string line,line2="create circle"; 
    for (int i=1;i<countrows();i++) 
    { 
     getline(myfile,line); 
     if (line.find(line2)!=string::npos) 
     { 
      istringstream ss(line); 
      ss>>k; 
      cout<<k<<endl; 

     } 

    } 
    return c; 

} 

,而不是即時得到ADRESS內存...幫助PLZ

+0

的'='後的數字總是?如果是這樣,只需要一個子字符串開始超過'='的一個字符,並在')'之前停止。將生成的字符串提供給一個「istringstream」並從中提取一個「int」。 – JorenHeit

回答

0

因爲行不以數字開頭。在提取數字之前,您需要跳過#operation=部分。

您應該檢查提取結果和getline,以幫助識別出現問題時出現問題。

此外,如果countrows()返回文件中的預期行數,則循環會錯過最後一行。要麼從零開始循環,要麼從i <= countrows();或者,如果要處理文件中的每一行,則只需循環while (getline(myfile,line))即可。

0

如果您嘗試讀取的文件中的實際文本以"#operation=1"開頭,並且您希望編號爲1,則不能使用簡單輸入算子。它將首先讀取字符'#',這不是一個數字,因此解析將失敗,並且k將不會被初始化。如果k沒有初始化,它將是不確定的值,讀取該值將導致未定義的行爲和看似隨機的輸出。

您需要檢查提取工作:

if (ss >> k) 
    std::cout << k << '\n'; 

這雖然不會解決你的問題,像我上面所說的,你不能在這裏使用簡單的輸入操作。您需要使用其他方法解析字符串。一種方法可能是找到相同的字符'='並在此之後獲取子字符串以嘗試提取數字。

0

編輯:一種方法做得不是很接近你嘗試使用atoi()而不是流的方式。

#include <iostream> 
#include <cstdlib> // for atoi() 
int main(){ 

    std::string str = "#operation=1(create circle and add to picture) name X Y radius."; 
    int k; 

    std::string line=str, line2="(create circle"; 

    std::size_t fnd = line.find(line2); 
    if (fnd!=std::string::npos) 
    { 
     k = atoi(&str[fnd-1]); // int atoi(const char *str) == argument to integer 
     std::cout<< k << " " << str[fnd-1] << str[fnd] << " "; 
    } 
} 

有幾種方式從字符串中提取的整數但我喜歡過濾掉從字符串的數字;

#include <iostream> 

int main(){ 

    std::string str = "#operation=1(create circle and add to picture) name X Y radius."; 
    int k = 0; 

    // an array of our base10 digits to filter through and compare 
    const char digit[] = {'0','1','2','3','4','5','6','7','8','9'}; 

    for(int s_filter = 0; s_filter<str.size(); ++s_filter){ 
     for(int d_filter = 0; d_filter<10; ++d_filter){ 
     // filter through each char in string and 
     // also filter through each digit before the next char 

      if(digit[d_filter] == str[s_filter]) { 
      // if so the char is equal to one of our digits 

       k = d_filter;// and d_filter is equal to our digit 
       break; 

      } else continue; 
     } 
    } 
    switch(k) { 
     case 1: 
      std::cout<< "k == 1"; 
      // do stuff for operation 1.. 
      return 0; 
     case 2: 
      std::cout<< "k != 1"; 
      // do more stuff 
      break; 
     //case 3: ..etc.. etc.. 
     default: 
      std::cout<< "not a digit"; 
      return 1; 
    } 
} 
+2

使用'strtol',它具有更強大的接口。 –

+0

感謝您指出這一點,我只是爲了簡單而使用'atoi',如果有人想要引用這個,那麼到'atoi'的鏈接提供一個鏈接到頁面底部的'strtol'。 – James

0

試試這個:

Circle Circle::CreateCirc(Circle c){ 
const std::streamsize ALL = std::numeric_limits<std::streamsize>::max(); // #include <limits> needed 
int k; 
ifstream myfile("cmd.txt"); 
if (!myfile.is_open()) 
    cout<<"Unable to open the requested file "<<endl; 
for (int i=1;i<countrows(); ++i, myfile.ignore(ALL,'\n')) // skip rest of the line 
{ 
    if(myfile.ignore(ALL,'=') >> k ) 
    { 
     cout<<k<<endl; 
    } 
    else 
     break; // read error 
} 
return c; 
} 
0
// find_num.cpp (cX) 2015 [email protected] 
// http://stackoverflow.com/questions/21115457/ 

#include <string> // std::string 
#include <cctype> // isnum 

/// Find the number in 'str' starting at position 'pos'. 
/// Returns the position of the first digit of the number. 
/// Returns std::string::npos when no further numbers appear within 'str'. 
/// Returns std::string::npos when 'pos >= str.length()'. 
size_t find_num(const std::string str, size_t pos) { 
    size_t len = str.length(); 
    bool isNegative = false; 
    while (pos < len) { 
     if (isdigit(str[pos])) { 
      return (isNegative ? pos-1 : pos); 
     } 
     else if (str[pos]=='-') { 
      isNegative = true; 
     } 
     else { 
      isNegative = false; 
     } 
     ++pos; 
    } 
    return std::string::npos; 
} 

#include <cassert>  // assert() 
#include <cstring>  // strlen(); 

int main() { 
    std::string str; 

    str = ""; 
    assert(std::string::npos == find_num(str, 0)); 
    assert(std::string::npos == find_num(str, 9)); 

    str = "#operation=1(create circle and add to picture) name X Y radius."; 
    assert(strlen("#operation=") == find_num(str, 0)); 

    str = "abcd 111 xyx 12.33 alpha 345.12e-23"; 
    ///.123456789.123456789.123456789. 
    assert( 5 == find_num(str, 0)); 
    assert(   13 == find_num(str, 5+3)); 
    assert(      25 == find_num(str, 20)); 

    str = "abcd-111 xyx-12.33 alpha-345.12e-23"; 
    ///.123456789.123456789.123456789. 
    assert( 4 == find_num(str, 0)); 
    assert(   12 == find_num(str, 5+3)); 
    assert(      24 == find_num(str, 20)); 

    str = "-1"; 
    assert(0 == find_num(str, 0)); 
    assert(1 == find_num(str, 1)); 
    assert(std::string::npos == find_num(str, 2)); 
    assert(std::string::npos == find_num(str, strlen("-1"))); 

    return 0; 
}