4

Java では、文字列にcharAt()機能があります。

C++ では、その関数は単純にstringname[INDEX]

しかし、整数の特定のインデックスで特定の数値を使用したい場合はどうすればよいでしょうか?

例えば

int value = 9123;

インデックス 0 で作業したいとしましょう。これはちょうど 9 です。

整数で index at を使用する方法はありますか?

4

10 に答える 10

15
int value = 9123;
std::stringstream tmp;
tmp << value;
char digit = (tmp.str())[0];
于 2012-04-10T06:56:51.140 に答える
9

いいえ、整数から 10 進数を抽出する標準関数はありません。

C++11 には、文字列に変換する関数があります。

std::string string = std::to_string(value);

C++11 を使用できない場合は、文字列ストリームを使用できます。

std::ostringstream stream;
stream << value;
std::string string = stream.str();

または古い学校の C 形式:

char buffer[32];  // Make sure it's large enough
snprintf(buffer, sizeof buffer, "%d", value);
std::string string = buffer;

または、1桁だけが必要な場合は、算術的に抽出できます。

int digits = 0;
for (int temp = value; temp != 0; temp /= 10) {
    ++digits;
}

// This could be replaced by "value /= std::pow(10, digits-index-1)"
// if you don't mind using floating-point arithmetic.
for (int i = digits-index-1; i > 0; --i) {
    value /= 10;
}
int digit = value % 10;

賢明な方法で負の数を処理することは、読者の演習として残されています。

于 2012-04-10T06:59:56.097 に答える
8

次の式 (疑似コード) を使用できます。

currDigit = (absolute(value) / 10^index) modulo 10; // (where ^ is power-of)
于 2012-04-10T07:00:39.183 に答える
1

最下位桁に 0 を使用する別のソリューション。は、書かれた順序で個々の数字にdigits分解するために使用されます。value(つまり、「9347」は 9,3,4,7 になります)。次に、最初の値を破棄しindexます。つまり、3 桁目を取得するには、最初の 2 桁を破棄して新しい前線を取ります。

if (value==0 && index ==0) return 0; // Special case.
if (value <0) { ... } // Unclear what to do with this.
std::list<char> digits;
while (value) {
  digits.push_front(value % 10);
  value /= 10;
}
for(; index > 0 && !digits.empty(); index--) {
  digits.pop_front();
}
if (!digits.empty()) {
  return digits.front();
} else
{
  throw std::invalid_argument("Index too large");
}
于 2012-04-10T07:21:18.070 に答える
1

物事を完全にするために、boost::lexical_castを使用することもできます。詳細については、こちらのドキュメントをご覧ください。

基本的には、 Andreas Brinck answearで見つけることができるコードの素敵なラッパーです。

于 2012-04-10T07:05:05.280 に答える
0

提案されたすべての修正と問題が解決された、giorashcのソリューションのバリアントを実装しました。少し長いですが、すべてがインライン化されている場合は高速になるはずです。コードのほとんどは、完全を期すために残したテストです。

#include <iostream>
#include <math.h>

char get_kth_digit( int v, int index)
{
  assert(v>0);
  int mask = pow(10,index);
  return '0'+(v % (mask*10))/mask;
}

int count_digits( int v )
{
  assert(v>0);

  int c=0;
  while(v>0)
  {
    ++c;
    v/=10;
  }

  return c;
}

char get_int_index(int v, int index)
{
  if( v==0 ) return '0';
  if( v <  0 )
  {
    if(index==0) { return '-'; }
    return get_int_index(-v,index-1);
  }

  // get_kth_digit counts the wrong way, so we need to reverse the count
  int digits = count_digits(v);
  return get_kth_digit( v, digits-index-1);
}



template<typename X, typename Y>
void compare(const X & v1, const Y & v2, const char * v1t, const char * v2t, uint32_t line, const char * fname )
{
  if(v1!=v2)
  {
    std::cerr<<fname<<":"<<line<<": Equality test failed "<< v1t  << "("<<v1<<") <> " << v2t <<" ("<<v2<<")"<<std::endl;
  }
}

#define test_eq(X,Y) compare(X,Y,#X,#Y,__LINE__,__FILE__)

int main()
{
  test_eq( 1, count_digits(1) );
  test_eq( 1, count_digits(9) );
  test_eq( 2, count_digits(10) );
  test_eq( 2, count_digits(99) );
  test_eq( 3, count_digits(100) );
  test_eq( 3, count_digits(999) );

  test_eq( '1', get_kth_digit(123,2) );
  test_eq( '2', get_kth_digit(123,1) );
  test_eq( '3', get_kth_digit(123,0) );

  test_eq( '0', get_kth_digit(10,0) );
  test_eq( '1', get_kth_digit(10,1) );

  test_eq( '1', get_int_index(123,0) );
  test_eq( '2', get_int_index(123,1) );
  test_eq( '3', get_int_index(123,2) );

  test_eq( '-', get_int_index(-123,0) );
  test_eq( '1', get_int_index(-123,1) );
  test_eq( '2', get_int_index(-123,2) );
  test_eq( '3', get_int_index(-123,3) );

}
于 2012-04-10T07:46:53.490 に答える
0

整数は文字列ではないため、それを行うことはできません。実際に必要なのは、整数を文字列に変換することです。itoaを使用するか、こちらをご覧ください。

于 2012-04-10T06:55:01.137 に答える
0

sprintf を試して、整数を文字列に書き出します。

http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

次に、印刷したばかりの char 配列にインデックスを付けることができます。

于 2012-04-10T06:55:12.310 に答える
0

私はそれを文字列に変換してからインデックスを付けます-CPPには次のものもあります:

str.at(i) 

Java と同様の機能。

C++11 のもう 1 つの単純なループは、範囲ベースのループです。

int i = 0
for(auto s : int_or_str){
    if(i == idx)
        cout << s;
    else
        i++  
}

これは標準の for ループよりも簡単ではないと思います。これが答えであることは知っていますが、私はシンプルでなじみのある答えを好みます。

ザック

于 2019-07-31T00:44:57.457 に答える
0

Andreas Brinkに敬意を表したロングバージョン。

C++ ライブラリは、「シーケンス」と「値」の間に「ストリーム」という名前の「メディエーター」が存在するように設計されており、実際には値から対応するシーケンスへのトランスレーターとして機能します。

「シーケンス」は、具体的な実装が「文字列」と「ファイル」である抽象的な概念です。「ストリーム」は、対応する具体的な実装が「stringstream」と「fstream」である別の抽象概念であり、ヘルパー クラス「stringbuf」と「filebuf」(どちらも抽象「streambuf」から派生) およびヘルパー オブジェクトから実装されます。いくつかの「ファセット」を含む「ロケール」クラスの。

引用された回答コードは、次のように機能します。

  1. classのtmpオブジェクトstringstreamはデフォルトで構築されます: これは内部的に astingbufと aを構築しstring、さらにlocaleシステム グローバル ロケールのファセットを参照する a を構築します (デフォルトのロケールは "classic" または "C" ロケールを再マップします)。
  2. ストリームと関数のoperator<<間が呼び出されます。すべての基本型に対して、そのうちの 1 つがあります。int
  3. 「int バージョン」はnum_putロケールからファセットを取得し、バッファから「バッファ イテレータ」を取得してput、指定されたストリームのフォーマット フラグを渡す関数を呼び出します。
  4. 「プット関数」は実際に数字を文字シーケンスに変換し、バッファを埋めます
  5. バッファーがいっぱいになるか、特定の文字が挿入されるか、str関数が呼び出されると、バッファーの内容が文字列に "送信" (この場合はコピー) され、文字列の内容が返されます。

この非常に複雑なプロセスは一見複雑に見えますが、

  • 完全に非表示にすることができます (2 行のコードになります)
  • カムは事実上何でも拡張できます...
  • 多くの場合、ほとんどの C++ コースとチュートリアルでは、その詳細が (一種の) 悲惨な状態に保たれています。
于 2012-04-10T07:32:38.347 に答える