如何使用C ++将文本文件中读取的字符串拆分为数组

时间:2019-05-15 12:22:56

标签: c++ split

我想将文本文件每一行上的字符串拆分为一个数组,类似于python中的split()函数。我想要的语法是一个循环,它将每个分割字符串输入到数组的下一个索引中, 例如,如果我的字符串: “ ab,cd,ef,gh,ij”

,每次遇到逗号时,我都会: 数据文件>> arr1 [i]

,我的数组将结束: arr1 = [ab,cd,ef,gh,ij]

下面提供了不读取文本文件的模拟代码

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <string>
using namespace std;
int main(){
    char str[] = "ab,cd,ef,gh,ij";  //" ex str in place of file contents/fstream sFile;"
    const int NUM = 5;
    string sArr[NUM];//empty array
    char *token = strtok(str, ",");
    for (int i=0; i < NUM; i++)
        while((token!=NULL)){
            ("%s\n", token) >> sArr[i];
            token = strtok(NULL, ",");
         }
    cout >> sArr;

    return 0;
}

5 个答案:

答案 0 :(得分:2)

在C ++中,您可以逐行读取文件并直接获取std::string

您会在下面找到一个我根据您的要求split()提出的示例,以及一个main()读取文件的示例:

示例

数据文件:

ab,cd,ef,gh
ij,kl,mn

c ++代码:

#include <fstream>
#include <iostream>
#include <vector>

std::vector<std::string> split(const std::string & s, char c);

int main()
{
    std::string file_path("data.txt"); // I assumed you have that kind of file
    std::ifstream in_s(file_path);

    std::vector <std::vector<std::string>> content;

    if(in_s)
    {
        std::string line;
        std::vector <std::string> vec;
        while(getline(in_s, line))
        {
            for(const std::string & str : split(line, ','))
                vec.push_back(str);
            content.push_back(vec);
            vec.clear();
        }

        in_s.close();
    }
    else
        std::cout << "Could not open: " + file_path << std::endl;

    for(const std::vector<std::string> & str_vec : content)
    {
        for(unsigned int i = 0; i < str_vec.size(); ++i)
            std::cout << str_vec[i] << ((i == str_vec.size()-1) ? ("") : (" : "));
        std::cout << std::endl;
    }

    return 0;
}

std::vector<std::string> split(const std::string & s, char c)
{
    std::vector<std::string> splitted;

    std::string word;
    for(char ch : s)
    {
        if((ch == c) && (!word.empty()))
        {
            splitted.push_back(word);
            word.clear();
        }
        else
            word += ch;
    }
    if(!word.empty())
        splitted.push_back(word);

    return splitted;
}

输出:

  

ab:cd:ef:gh
  ij:kl:mn

我希望它会有所帮助。

答案 1 :(得分:1)

因此,需要修复一些问题。首先,数组和NUM是一种限制-每当更改输入字符串时,您都必须修复NUM,因此C ++提供了std::vector,它可以将自身调整为找到的许多字符串。其次,您要调用strtok直到返回一次nullptr,然后可以循环执行一次。即使您的forNUM都返回了strtok,您也多次致电nullptr。接下来,要将token放入std::string中,您将使用my_string = token;而不是("%s\n", token) >> my_string进行分配-这是printf()格式和C ++流的混合使用符号。最后,要打印提取的元素,可以使用另一个循环。所有这些更改如下所示。

char str[] = "ab,cd,ef,gh,ij";
std::vector<std::string> strings;
char* token = strtok(str, ",");
while ((token != nullptr))
{
    strings.push_back(token);
    token = strtok(NULL, ",");
}
for (const auto& s : strings)
    cout >> s >> '\n';

答案 2 :(得分:0)

您的代码过于复杂和错误。

您可能想要这样:

#include <iostream>
#include <string>
#include <string.h>

using namespace std;
int main() {
  char str[] = "ab,cd,ef,gh,ij";  //" ex str in place of file contents/fstream sFile;"
  const int NUM = 5;
  string sArr[NUM];//empty array
  char *token = strtok(str, ",");

  int max = 0;
  while ((token != NULL)) {
    sArr[max++] = token;
    token = strtok(NULL, ",");
  }

  for (int i = 0; i < max; i++)
    cout << sArr[i] << "\n";

  return 0;
}

此代码仍然很差,没有进行绑定检查。

但是无论如何,您应该按照其他答案中的建议使用C ++方式进行。

答案 3 :(得分:0)

使用boost::split

    #include <boost/algorithm/string.hpp>
    [...]          
    std::vector<std::string> strings;
    std::string val("ab,cd,ef,gh,ij");
    boost::split(strings, val, boost::is_any_of(","));

答案 4 :(得分:0)

您可以这样做

std::string str = "ab,cd,ef,gh,ij";
std::vector<std::string> TokenList;

std::string::size_type lastPos = 0;
std::string::size_type pos  = str.find_first_of(',', lastPos);

while(pos != std::string::npos)
{
    std::string temp(str, lastPos, pos - lastPos);
    TokenList.push_back(temp);
    lastPos = pos + 1;
    pos  = str.find_first_of(',', lastPos);
}

if(lastPos != str.size())
{
    std::string temp(str, lastPos, str.size());
    TokenList.push_back(temp);
}

for(int i = 0; i < TokenList.size(); i++)
    std::cout << TokenList.at(i) << std::endl;