简体   繁体   English

如何从字符串中提取整数? C ++

[英]how to extract integer from a string? c++

i have this line taken from a txt file (first line in the file): 我从txt文件中提取了这一行(文件的第一行):

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

why does this code doesnt take the integer 1 and puts it into k? 为什么此代码不采用整数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;

}

instead im getting adress memory...help plz 相反,我正在获取地址记忆...帮助PLZ

Because the line doesn't start with a number. 因为该行不是以数字开头。 You'll need to skip over the #operation= part before extracting a number. 在提取数字之前,您需要跳过#operation #operation=部分。

You should check the result of the extraction, and of getline , to help identify what's going wrong when these fail. 您应该检查提取结果和getline ,以帮助确定失败的原因。

Also, if countrows() returns the expected number of rows in the file, then your loop would miss out the last one. 另外,如果countrows()返回文件中的预期行数,则循环将错过最后一行。 Either loop from zero, or while i <= countrows() ; 从零开始循环,或者当i <= countrows() or, if you want to process every line in the file, you could simply loop while (getline(myfile,line)) . 或者,如果您要处理文件中的每一行,则可以简单地循环while (getline(myfile,line))

If the actual text in the file you try to read starts with "#operation=1" and you want the number 1 from that, you can't use the simple input operator. 如果您尝试读取的文件中的实际文本以"#operation=1"开头,并且您希望从中开始使用数字1 ,则不能使用简单的输入运算符。 It will read the character '#' first, which isn't a digit and so the parsing will fail and k will not be initialized. 它将首先读取字符'#' ,因为它不是数字,所以解析将失败,并且不会初始化k And if k is not initialized, it will be of indeterminate value, and reading that value will lead to undefined behavior and seemingly random output. 如果k未初始化,它将是不确定的值,读取该值将导致不确定的行为和看似随机的输出。

You need to check that the extraction worked: 您需要检查提取是否有效:

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

That won't solve your problem though, as like I said above, you can't use the simple input operator here. 但是,这不能解决您的问题,就像我上面说的那样,您不能在此处使用简单的输入运算符。 You need to parse the string using other methods. 您需要使用其他方法来解析字符串。 One way might be to find the equal character '=' and get a sub-string after that to try and extract the number. 一种方法可能是找到相等的字符'='然后获取一个子字符串以尝试提取数字。

EDIT: A way to do it not much bit a little closer to the way you were trying to do it using atoi() rather than streams. 编辑:一种方法来做它有点接近您尝试使用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] << " ";
    }
}

There are a few ways to extract an integer from a string but i like to filter out the digit from the string; 有几种方法可以从字符串中提取整数,但我喜欢从字符串中过滤出数字;

#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;
    }
}

try this: 尝试这个:

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;
}
// find_num.cpp (cX) 2015 adolfo.dimare@gmail.com
// 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";
    ///    0123456789.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";
    ///    0123456789.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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM