如何使用string.substr()函数?

46
我想制作一个程序,它可以读取一些以字符串格式表示的数字,并输出如下:如果数字是12345,则应输出12 23 34 45。我尝试使用C++字符串库中的substr()函数,但它给我奇怪的结果 - 输出结果为1 23 345 45,而不是预期的结果。为什么?
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main(void)
{
    string a;
    cin >> a;
    string b;
    int c;

    for(int i=0;i<a.size()-1;++i)
    {
        b = a.substr(i,i+1);
        c = atoi(b.c_str());
        cout << c << " ";
    }
    cout << endl;
    return 0;
}

1
不应使用 atoi - phuclv
8个回答

73
如果我没错的话,substr() 的第二个参数应该是子字符串的长度。那么怎么样呢?
b = a.substr(i,2);

?


2
是的,他每次都在增加子字符串的长度。 - Seth Moore

26

此处所示,substr的第二个参数是长度而不是结束位置:

string substr ( size_t pos = 0, size_t n = npos ) const;

生成子字符串

返回一个字符串对象,其内容初始化为当前对象的子字符串。该子字符串是从字符位置pos开始,并具有n个字符的字符序列。

对于i的值,您的代码行b = a.substr(i,i+1);将生成:

substr(0,1) = 1
substr(1,2) = 23
substr(2,3) = 345
substr(3,4) = 45  (since your string stops there).

你需要的是b = a.substr(i,2);

你还应该注意,对于像12045这样的数字,你的输出看起来会很奇怪。由于你正在使用atoi()在字符串部分上,并输出该整数,你将获得12 20 4 45。你可能想尝试直接输出字符串本身,它将会是两个字符长度:

b = a.substr(i,2);
cout << b << " ";

事实上,整个东西可以更简单地写成:

#include <iostream>
#include <string>
using namespace std;
int main(void) {
    string a;
    cin >> a;
    for (int i = 0; i < a.size() - 1; i++)
        cout << a.substr(i,2) << " ";
    cout << endl;
    return 0;
}

3

另一个有趣的变体问题是:

如何在不使用其他字符串的情况下将 "12345" 转换为 "12 23 34 45"

以下做法可行吗?

    for(int i=0; i < a.size()-1; ++i)
    {
        //b = a.substr(i, 2);
        c = atoi((a.substr(i, 2)).c_str());
        cout << c << " ";
    }

3

substr(i,j) 意味着你从索引 i 开始(假设第一个索引是 0),并取下一个 j 个字符。 它并不意味着一直到索引 j


2
你可以使用以下c代码来获得上述输出。
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
  char *str;
  clrscr();
  printf("\n Enter the string");
  gets(str);
  for(int i=0;i<strlen(str)-1;i++)
  {
    for(int j=i;j<=i+1;j++)
      printf("%c",str[j]);
    printf("\t");
  }
  getch();
  return 0;
}

1
这正是你不应该做的事情:http://powerfield-software.com/?p=829 - paxdiablo

2
不使用substr()的可能解决方案。
#include<iostream>
#include<string>

using namespace std;


int main() {
    string c="12345";
    int p=0;

    for(int i=0;i<c.length();i++) {
        cout<<c[i];
        p++;

        if (p % 2 == 0 && i != c.length()-1) {
            cout<<" "<<c[i];
            p++;
        }
    }
}

1

使用字符串构造函数可以获取子字符串的副本。

string(const string& str, size_t pos, size_t n) 

例如:

...

b = string(a, i, 2); // substring of a from position i, including 2 characters

这与 substr 不同之处在于长度 n 不能省略。我只提供这个作为一种替代方案,而不是改进。


0

使用 string_view 的可能解决方案

void do_it_with_string_view( void )
{
    std::string a { "12345" };
    for ( std::string_view v { a }; v.size() - 1; v.remove_prefix( 1 ) )
        std::cout << v.substr( 0, 2 ) << " ";
    std::cout << std::endl;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接