4

在 Java 中,字符串有一个charAt()功能。

在 C++ 中,该函数很简单stringname[INDEX]

但是,如果我想在整数的某个索引处使用特定数字怎么办?

例如

int value = 9123;

假设我想使用索引 0,也就是 9。

有没有办法将索引与整数一起使用?

4

10 回答 10

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

不,没有从整数中提取十进制数字的标准函数。

在 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;

或者如果你只想要一个数字,你可以算术提取它:

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

为了使事情更完整,您还可以使用boost::lexical_cast,有关更多信息,请查看此处的文档。

基本上它只是一个很好的代码包装器,可以在Andreas Brinck answear 找到。

于 2012-04-10T07:05:05.280 回答
1

另一种解决方案,它确实使用 0 作为最小的数字。digits用于按书面顺序分解value成单个数字。(即“9347”变为 9,3,4,7)。然后我们丢弃第一个index值。即为了得到第三个数字,我们丢弃前两个并采取新的前沿。

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 回答
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

Andreas Brink的较长版本。

C++ 库的设计使得在“序列”和“值”之间有一个名为“流”的“中介”,它实际上充当了从值到其相关序列的翻译器。

“序列”是一个抽象概念,其具体实现是“字符串”和“文件”。“stream”是另一个抽象概念,其对应的具体实现是“stringstream”和“fstream”,它们是根据帮助类“stringbuf”和“filebuf”(都派生自抽象“streambuf”)和帮助对象实现的的“语言环境”类,包含一些“方面”。

引用的答案代码以这种方式工作:

  1. tmpclass的对象stringstream是默认构造的:这还将在内部构造 astingbuf和 a string,加上locale引用系统全局语言环境的方面(默认重新映射“经典”或“C”语言环境)
  2. 和函数operator<<之间的调用:有一个,对于所有基本类型int
  3. “int 版本”num_put从语言环境中获取 facet,并从缓冲区中获取“缓冲区迭代器”,并调用put传递给定流的格式标志的函数。
  4. “放置函数”实际上将数字转换为字符序列,从而填充缓冲区
  5. 当缓冲区已满,或插入特定字符或str调用函数时,缓冲区内容被“发送”(在本例中为复制)到字符串,并返回字符串内容。

这个非常复杂的过程起初看起来很复杂,但是:

  • 可以完全隐藏(产生两行代码)
  • 凸轮几乎可以扩展到任何东西,但...
  • 在大多数 C++ 课程和教程中,它的细节经常被保留为(某种)痛苦
于 2012-04-10T07:32:38.347 回答
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

我会将其转换为字符串,然后对其进行索引——CPP 还具有:

str.at(i) 

功能类似于 Java 的。

C++11 中另一个更简单的循环是基于范围的循环——

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

我想这并不比标准 for 循环容易——认为 auto 可能有帮助,不是真的。我知道这是有答案的,但我更喜欢简单而熟悉的答案。

扎克

于 2019-07-31T00:44:57.457 回答