【问题标题】:array size and split of string数组大小和字符串拆分
【发布时间】:2013-07-30 20:41:16
【问题描述】:

好吧,我不得不编写一个程序来拆分字符串的元素。然后打印这些话。 我面临一些问题: 1)该数组打印的字符串超过了我希望它应该在打印最后一个单词后立即结束打印的字符串的大小。我试图阻止这种情况,但是当我尝试在最后一个单词时中断时,它总是会出现运行时错误。 2)还有其他有效的分割打印方式吗???

#include <sstream>
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include <string>   

using namespace std;

int main()
{
    std::string line;
    std::getline(cin, line);
    string arr[1000];
    int i = 0;
    int l=line.length();
    stringstream ssin(line);

    while (ssin.good() && i < l)
    {
        ssin >> arr[i];
        ++i;
    }

    int size = sizeof(arr) / sizeof(arr[0]);

    for(i = 0; i <size; i++){
        cout << arr[i] << endl;
    }

    return 0;
}

【问题讨论】:

  • 请修正你的代码缩进:)
  • 尝试 while (ssin >> arr[i++]);
  • 已修复 :) 现在好了???
  • 也回应了额外的打印部分拆分是由我编写的额外打印部分的代码完成的
  • @AlokSrivastava 不完美,但我会帮助你。

标签: c++ string split


【解决方案1】:
int size = sizeof(arr) / sizeof(arr[0]);

这是一个编译时间值,它始终是数组中元素的数量 (1000)。它不知道您在循环中分配了多少个字符串。您将成功读取的字符串数(加 1)存储在 i 变量中,因此您可以这样做:

int size = i - 1;

但如果由我决定,我会使用可增长的结构,例如向量 (#include &lt;vector&gt;)

std::vector<std::string> arr;
std::string temp;
while (ssin >> temp)
{
    arr.push_back(temp);
}

for (auto const & str : arr)
{
    std::cout << str << std::endl;
}

/* If you're stuck in the past (can't use C++11)
    for (std::vector<std::string>::iterator = arr.begin(); i != arr.end(); ++i)
    {
        std::cout << *i << std::endl;
    }
*/

对于基于通用字符的拆分,我更喜欢boost::split(我知道你不能使用它,但供将来参考)

std::vector<std::string> arr;
boost::split(arr, line, boost::is_any_of(".,;!? "));

【讨论】:

  • 如果我是问题作者,我会将其标记为答案。它非常优雅和详尽
【解决方案2】:

阅读函数 strtok。它是老派,但非常易于使用。

【讨论】:

  • 或者更好,strtok_r()。太糟糕了,这个答案会因为不使用好的标准库类而被不赞成和反对。还有 jQuery。
【解决方案3】:

1) 您应该对程序进行一些更改:

  #include <sstream>
  #include <iostream>
  #include <string>   
  using namespace std;
  int main()
  {
    std::string line("hello string world\n");
    string arr[1000];
    int i = 0;
    stringstream ssin(line);
    while (ssin.good() && i < 1000)
    {
      ssin >> arr[i++];
    }
    int size = i-1;
    for(i = 0; i < size; i++){
      cout << i << ": " << arr[i] << endl;
    }
    return 0;
  }

也就是说,您不想打印sizeof(arr)/sizeof(arr[0])(即1000)个元素。条件i &lt; l没有意义

2) stringstream 如果您只想分隔单个字符串,则可以;如果需要更多,请使用boost/tokenizer 拆分字符串。它是现代 c++,一旦你尝试过,你将永远不会回来!

【讨论】:

  • 抱歉,这些靴子在通过各种编码网站提交的程序中不起作用:(
【解决方案4】:

这是我认为现在不用担心的最好方法

#include <sstream>
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include <cstring>
#include <string>   
using namespace std;
int main ()
{
std::string str;
std::getline(cin, str);
string arr[100];
int l=0,i;

char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());

 // cstr now contains a c-string copy of str

char * p = std::strtok (cstr,".,;!? ");
while (p!=0)
 {
//std::cout << p << '\n';
arr[l++]=p;
p = strtok(NULL,".,;!? ");
}
for(i = 0; i <l; i++)
{
    cout << arr[i] << endl;
}

delete[] cstr;
return 0;
}

【讨论】:

    猜你喜欢
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多