2

私の本には、整数にコンマを入力してプログラムを台無しにする人々についての通過コメントがありましたが、それは詳しく説明していませんでした。それで考えさせられたので、std :: stringを取得して、すべての非整数文字を削除する小さなアルゴリズムを書いてみました。このコードはコンパイルされますが、出力をスキップします。newstringに何も割り当てられていないのはなぜですか?if(isdigit(fstring [i]))は、数字を保持するために指しているアドレスについてtrueと評価されますか?

//little algorithm to take the non-integers out of a string
//no idea on efficiency

#include <iostream>
#include <string>

int main()
{
    std::cout << "Enter a number with non-integer characters: ";

    std::string fstring; 
    getline(std::cin, fstring);

    std::string newstring;

    int i = 0, x = 0;

    while (i != fstring.length())
    {
        if (isdigit(fstring[i]))
        {
            newstring[x] = fstring[i];
            i++;
            x++;
        }
        else
        {
           i++;
        }
    }

    std::cout << std::endl;
    std::cout << newstring;
    system("PAUSE");
}

二次的な質問、それはおそらく他の場所に属します:文字列をint(または浮動小数点数)にどのように変換しますか?

4

5 に答える 5

6

newstring の長さは 0 なので、x=0 の場合の newstring[x] は実際には不正です。次を使用して文字列に追加する必要があります: newstring.append(1, fstring[i])

2 番目の質問については、atoi()、atof()、strtol(0、strtof() 関数を探します。

于 2009-05-03T00:40:00.187 に答える
5

文字列は配列に似ていますが、文字列の既定のコンストラクターは空の文字列を作成します。必要以上のメモリを割り当てる必要があるのはなぜですか? あったとしても、どれくらいか、または fstring のフィルター処理されたコピーに十分な大きさになるかどうかはわかりません。崩れないのが印象的です。

簡単な変更は、次のように変更することです。

std::string newstring;

に:

 std::string newstring(fstring.length(), '\0')

ループの後に次を追加します。

 newstring.resize(x);

これによりnewstring、フィルタリング中に少なくとも十分なスペース (おそらくそれ以上) が確保され、フィルタリングが終了したときに適切なサイズにトリミングされます。std::remove_copy_ifの関数にも興味があるかもしれません<algorithm>

例えば

struct isnotdigit { bool operator()(char c) { return !isdigit(c); } };

std::string newstring(fstring.length(), '\0');
std::string::iterator i = std::remove_copy_if(fstring.begin(), 
  fstring.end(), newstring.begin(), isnotdigit());
newstring.erase(i, newstring.end());

文字列を整数/浮動小数点数に変換する場合、前述の、、 、などの関数に加えてatoi、iostream ライブラリを使用することもできます。strtolatofstrtof

 #include <sstream>
 std::string integer("23");
 std::istringstream iss(integer);
 int result;
 iss >> result;

 std::string floatingpoint("3.14");
 std::istringstream iss2(floatingpoint);
 double result2;
 iss2 >> result2;

また、printf ファミリの関数に精通している場合は、興味があるかもしれませんscanfsscanf

 const char *s = "23";
 int result;
 sscanf(s, "%d", &result);
于 2009-05-03T01:22:41.597 に答える
2

Shing Yipの答えの拡張:

数字以外を削除するには:

#include <iostream>
#include <functional>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    string fstring;
    getline(cin, fstring);
    fstring.erase(
        remove_if(fstring.begin(), fstring.end(),
            not1(ptr_fun(static_cast<int(*)(int)>(isdigit)))
        ),
        fstring.end()
    );

    cout << fstring << "\n";
}

ただし、なぜそのstatic_castが必要なのかわかりません。それがないとisdigitについて何かが曖昧だと思います。[編集:「名前空間stdの使用」を行わない場合は必要ないので、サンプルコードを書くのが面倒であるのは私のせいです。]

これが独自のループをロールするよりも簡単かどうかは議論の余地があります。

#include <iostream>
#include <string>

using namespace std;

int main() {
    string fstring, ins;
    getline(cin, ins);
    for (string::iterator it = ins.begin(); it != ins.end(); ++it) {
        if (isdigit(*it)) fstring.push_back(*it);
    }
    cout << fstring << "\n";
}

また、C ++ 0xにはcopy_ifがありますが、これは基本的に偶然に省略されており、実装は簡単です。

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

int main() {
    std::string fstring, ins;
    std::getline(std::cin, ins);
    std::copy_if(ins.begin(), ins.end(), 
        std::back_inserter(fstring), isdigit);
    std::cout << fstring << "\n";
}

int(またはfloat)に変換するには:

int i = boost::lexical_cast<int>(fstring);

または、ブーストがない場合:

#include <sstream>

int i = 0;
std::stringstream(fstring) >> i;

iを初期化する必要があることに注意してください。そうしないと、fstringが空の場合は設定されません。

于 2009-05-03T11:34:23.530 に答える
1

数字を削除するには:

fstring.erase(
      std::remove_if(fstring.begin(), fstring.end(), &isdigit), 
      fstring.end());

文字列を int/float/... に変換するには:

int n1 = boost::lexical_cast<int>("123");
float n2 = boost::lexical_cast<float>("123.456");
于 2009-05-03T04:05:52.703 に答える
0
  • 文字列から浮動小数点数へ:

必要がある#include <cstdlib>

float strtof(const char *nptr, char **endptr);

例えば:

 float f = strtof("3.4",NULL);
  • 文字列から整数へ

必要がある#include <cstdlib>

int atoi(const char *numPtr);

これらは C++ ではなく C 関数であるため、C 文字列を取得するには std::string で c_str() メソッドを使用する必要があることに注意してください。

const char* c_str ( ) const;
于 2009-05-03T01:13:22.133 に答える