C++ 如何在getline上使用delimeter

C++ 如何在getline上使用delimeter,c++,C++,我有一个文件,我应该读取每一行,并将其存储在数组结构中,我正在读取该文件,但结果是混合的,因为数据是用逗号分隔的,我如何让它读取用逗号分隔的行 struct Data{ std::string a; std::string b; std::string c; } int main(){ Data cd[100]; std::ifstream inFile; std::string data; inFile.open("data.txt");

我有一个文件,我应该读取每一行,并将其存储在数组结构中,我正在读取该文件,但结果是混合的,因为数据是用逗号分隔的,我如何让它读取用逗号分隔的行

struct Data{
    std::string a;
    std::string b;
    std::string c;
}

int main(){
Data cd[100];

std::ifstream inFile;  
std::string data;
inFile.open("data.txt");                 
if(inFile.good()){                       
    while(getline(inFile, data)){ //when I add, ',' right after data nothing shows up 
        std::stringstream ss(data);     
        ss >>cd[0].a >> cd[0].b >> cd[0].c;
        std::cout <<cd[0].a<<std::endl;
    }
}
else{
std::cout << "can't open" << std::endl;
}

inFile.close();    
//close the file
return 0;
}
struct数据{
std::字符串a;
std::字符串b;
std::字符串c;
}
int main(){
数据光盘[100];
std::ifstream-infle;
std::字符串数据;
infle.open(“data.txt”);
如果(infle.good()){
而(getline(infle,data)){//当我添加,,'时,数据之后什么也不显示
std::stringstream ss(数据);
ss>>cd[0].a>>cd[0].b>>cd[0].c;

std::cout您的
结构后缺少分号,并且在每个循环期间总是覆盖100个结构数组中的第一个结构:最简单的解决方案是创建一个索引计数器,它将随着每行的增加而增加。
若要在用户定义的分隔符上进行拆分,C++标准库没有预先设置的函数:要么使用Boost或滚动自己的解决方案。
i、 像这样的

#include <string>
#include <fstream>
#include <iostream>

struct Data {
  std::string a;
  std::string b;
  std::string c;
};

int main() {
  Data cd[100];
  size_t index = 0;
  std::ifstream inFile;
  std::string data;
  inFile.open("data.txt");
  if (inFile.good()) {
    while (getline(inFile, data)) { //when I add, ',' right after data nothing shows up 
      std::string::size_type startPos = data.find_first_not_of(",", 0); /* skip leading delimiters */
      std::string::size_type endPos = data.find_first_of(",", startPos); /* find first real delimiter */
      cd[index].a = data.substr(startPos, endPos - startPos); /* save substring */
      startPos = data.find_first_not_of(",", endPos); /* find next start position */
      endPos = data.find_first_of(",", startPos); /* find next endPosition */
      cd[index].b = data.substr(startPos, endPos - startPos); /* save substring */
      startPos = data.find_first_not_of(",", endPos); /* find next start position */
      endPos = data.find_first_of(",", startPos); /* find next endPosition */
      cd[index].c = data.substr(startPos, endPos - startPos); /* save substring */
      ++index;
    }
  }
  else {
    std::cout << "can't open" << std::endl;
  }
  inFile.close();
  //close the file
  return 0;
}
#包括
#包括
#包括
结构数据{
std::字符串a;
std::字符串b;
std::字符串c;
};
int main(){
数据光盘[100];
尺寸指数=0;
std::ifstream-infle;
std::字符串数据;
infle.open(“data.txt”);
if(infle.good()){
而(getline(infle,data)){//当我添加,,'时,数据之后什么也不显示
std::string::size_type startPos=data.find_first_not_of(“,”,0);/*跳过前导分隔符*/
std::string::size_type endPos=data.find_first_of(“,”,startPos);/*find first real delimiter*/
cd[index].a=data.substr(startPos,endPos-startPos);/*保存子字符串*/
startPos=data.find_first_not_of(“,”,endPos);/*find next start position*/
endPos=data.find_first_of(“,”,startPos);/*find next endPosition*/
cd[index].b=data.substr(startPos,endPos-startPos);/*保存子字符串*/
startPos=data.find_first_not_of(“,”,endPos);/*find next start position*/
endPos=data.find_first_of(“,”,startPos);/*find next endPosition*/
cd[index].c=data.substr(startPos,endPos-startPos);/*保存子字符串*/
++指数;
}
}
否则{

std::cout这可能在许多情况下对您有所帮助。打开您的文件,将文本逐行读取到std::字符串中。然后,这个有用的实用程序功能非常有用

实用程序.h

#ifndef UTILITY_H
#define UTILITY_H

#include <string>

class Utility {
public:    
    static std::vector<std::string> splitString( const std::string& strStringToSplit, const std::string& strDelimiter, const bool keepEmpty = true );

private:
    Utility(); // Private - Not A Class Object
    Utility( const Utility& c ); // Not Implemented
    Utility& operator=( const Utility& c); // Not Implemented
};

#endif // UTILITY_H
其中每个单词都是逗号分隔的,没有空格。您可以使用任何字符作为定义分隔符,可以是空格、冒号、分号、连字符等。这是一个非常有用和方便的实用函数,可以在许多情况下反复使用;尤其是当您试图解析文件或字符串时。现在您必须请注意,这将解析字符串。您仍然需要逐行读取文件,并将每行存储到字符串中,然后创建字符串向量来存储此函数的结果


一开始在类中使用这个函数似乎不直观,但我有十几个左右有用的实用函数,用于将字符串转换为大写和小写,将字符串转换为不同的基本数据类型,如int、float,甚至将由逗号分隔的值字符串转换为vec2、vec3和vec4对象,其中所有ese函数在一个不能实例化的类中声明为静态函数。它充当容器或包装器,几乎就像命名空间一样。换句话说,我的大多数独立字符串操作函数都会被大量使用,我最终会将它们包含在这个类中。

您回答说,您需要将其用作struc是的,你仍然可以。有不同的方法。现在根据你的问题和你提供的示例,你的结构有3个字符串,你需要它们的数组;让我们假设每行文本有3个字符串值,由一个逗号分隔。我创建了一个名为custom.txt的文本文件,这是它的内容:

custom.txt

Hello,world,how
are,you,today
每行正好有三个单词,用逗号分隔,没有空格:现在我将演示如何使用我在上一个答案中展示的实用函数,在读取一行文本后拆分字符串,然后在填充结构数组时解析它

#include <iostream>
#include <fstream>
#include <tchar.h>
#include <conio.h>
#include "Utility.h"

struct MyStruct {
    std::string str1;
    std::string str2;
    std::string str3;
}; // MyStruct

void parseLine( std::string& strLine, std::vector<std::string>& results, MyStruct& myStruct ) {
    results = Utility::splitString( strLine, std::string( "," ) );
    myStruct.str1 = results[0];
    myStruct.str2 = results[1];
    myStruct.str3 = results[2];
} // parseLine

bool readLine( std::fstream& in, std::string& line ) {
    if ( in.eof() ) {
        return false;
    }
    std::getline( in, line );
    return true;
} // readLine

int main() {
    std::string filename( "custom.txt" );
    std::string strLine;
    sd::fstream fin;

    fin.open( filename.c_str(), std::ios_base::in ) {
    if ( !fin.is_open() ) {
        std::cout << "Error reading in file " << filename << std::endl;
        return -1;
    }

    std::vector<std::string> results;
    // Since I only have 2 lines in this file 
    MyStruct myStruct[2];

    int line = 0;
    while ( readLine( fin, strLine ) ) {
        parseLine( strLine, results, myStruct[line] );
        line++;
    }

    std::cout << "Results: " << std::endl;
    for ( unsigned u = 0; u < 2; u++ ) {
        std::cout << myStruct[u].str1 << " " << myStruct[u].str2 << " " << myStruct[u].str3 << std::endl;
    }
    std::cout << std::endl;

    std::cout << "Press any key to quit." << std::endl;
    _getch();

    return 0;
} // main
#包括
#包括
#包括
#包括
#包括“Utility.h”
结构MyStruct{
std::字符串str1;
std::字符串str2;
std::字符串str3;
};//我的结构
void parseLine(std::string和strLine,std::vector和results,MyStruct和MyStruct){
结果=实用工具::拆分字符串(strLine,std::字符串(“,”);
myStruct.str1=结果[0];
myStruct.str2=结果[1];
myStruct.str3=结果[2];
}//语法分析行
bool readLine(std::fstream&in,std::string&line){
if(在.eof()中){
返回false;
}
std::getline(in,line);
返回true;
}//读线
int main(){
std::字符串文件名(“custom.txt”);
std::字符串strLine;
sd::fstream-fin;
打开(filename.c_str(),std::ios_base::in){
如果(!fin.is_open()){

std::你能发布data.txt的内容吗?我很感激,但我必须使用struct。你可以获取字符串向量中存储的每个单词,并从中填充结构,这是一个中间步骤。
Hello
World
How
Are
You
Today
!
Hello,world,how
are,you,today
#include <iostream>
#include <fstream>
#include <tchar.h>
#include <conio.h>
#include "Utility.h"

struct MyStruct {
    std::string str1;
    std::string str2;
    std::string str3;
}; // MyStruct

void parseLine( std::string& strLine, std::vector<std::string>& results, MyStruct& myStruct ) {
    results = Utility::splitString( strLine, std::string( "," ) );
    myStruct.str1 = results[0];
    myStruct.str2 = results[1];
    myStruct.str3 = results[2];
} // parseLine

bool readLine( std::fstream& in, std::string& line ) {
    if ( in.eof() ) {
        return false;
    }
    std::getline( in, line );
    return true;
} // readLine

int main() {
    std::string filename( "custom.txt" );
    std::string strLine;
    sd::fstream fin;

    fin.open( filename.c_str(), std::ios_base::in ) {
    if ( !fin.is_open() ) {
        std::cout << "Error reading in file " << filename << std::endl;
        return -1;
    }

    std::vector<std::string> results;
    // Since I only have 2 lines in this file 
    MyStruct myStruct[2];

    int line = 0;
    while ( readLine( fin, strLine ) ) {
        parseLine( strLine, results, myStruct[line] );
        line++;
    }

    std::cout << "Results: " << std::endl;
    for ( unsigned u = 0; u < 2; u++ ) {
        std::cout << myStruct[u].str1 << " " << myStruct[u].str2 << " " << myStruct[u].str3 << std::endl;
    }
    std::cout << std::endl;

    std::cout << "Press any key to quit." << std::endl;
    _getch();

    return 0;
} // main