【问题标题】:Reading separated data into an array structure c++将分离的数据读入数组结构c ++
【发布时间】:2014-09-02 11:28:21
【问题描述】:

我正在尝试读取由 ';' 分隔的数据成一个结构数组,所以我可以稍后过滤它们。 示例数据:

1.1 ; name1; 11-07-2014; 14:30
1.2 ; name2; 11-07-2017; 15:10

我不知道这个 .txt 文件中有多少条目。此外,我需要添加一个可能性来选择用户想要使用哪个文件(有效)我​​是 C++ 新手,所以我将不胜感激任何提示。

到目前为止,我已经创建了这个:

typedef struct{
    char numb[21];
    char names[100];
    char date[11];
    char time[6];
}vec;

vec *logs[200];

void_fastcall TForm1::Button1Click(TObject *Sender)
{
    OPENFILENAME ofn;
    char fname[MAX_PATH] ="";
    ZeroMemory( & ofn, sizeof( ofn ) );
    ofn.lStructSize = sizeof( ofn );
    ofn.lpstrFilter = "Text files (*.txt)\0*.txt\0All files\0*.*\0";
    ofn.nMaxFile = MAX_PATH;
    ofn.lpstrFile = fname;
    ofn.lpstrDefExt = "txt";
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;

    string line;

    if( GetOpenFileName( & ofn ) )
    {
        for(int i=0; i<200; i++){
            getline(fname, logs[i].numb, ';');
            getline(fname, logs[i].names, ';');
            getline(fname, logs[i].date, ';');
            getline(fname, logs[i].time, ';');   
        }
    }
}

我收到了这个错误 E2285 找不到匹配 'getline<_chart>(char *,undefined,char)'

【问题讨论】:

  • 使用getline 读取整行。然后,在该行内,找到分号。
  • logsvec * 的数组,但您没有使用正确的运算符。你应该使用logs[i]-&gt;numb。其次,您错误地使用了std::getline(假设是这样)。没有将char[] 作为第一个参数的重载。

标签: c++ getline


【解决方案1】:

我对您的代码感到困惑。 fname 是一个 LPTSTR,所以是一个字符串。这应该如何与 getline 一起使用?

我知道的唯一获取线函数是:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

或:

std::istream& std::getline(std::istream& is, std::string& str, char delim);
std::istream& std::getline(std::istream& is, std::string& str);

而且由于您使用GetOpenFileName,因此您在 Windows 上,这意味着您只能使用后者。无论如何,您需要实际打开一个文件进行阅读。

怎么样:

struct vec{
    std::string numb;
    std::string names;
    std::string date;
    std::string time;
};

std::vector<vec> logs;

size_t i = 0;
std::ifstream in(fname);
while (in.good() && i < 200)
{
    std::string line;
    getline(in, line);

    std::vector<std::string> bits = explode(line, ";");
    assert(bits.size() == 4);
    vec v = {bits[0], bits[1], bits[2], bits[3]};
    logs.push_back(v);        
    i++;
}

这是我方便的爆炸功能:

std::vector<std::string> explode(const std::string& str, const std::string& delimiter)
{
    std::vector<std::string> gibs;
    size_t start = 0;
    size_t end = 0;

    while ((start != std::string::npos) && (start < str.size()))
    {
        end = str.find(delimiter, start);

        std::string gib;
        if (end == std::string::npos)
        {
            gib = str.substr(start);
            start = std::string::npos;
        }
        else
        {
            gib = str.substr(start, end - start);
            start = end + delimiter.size();
        }
        gibs.push_back(gib);
    }

    return gibs;
}

最后决定是否要编程 C 或 C++。将两者混合从来都不是一个好主意。

【讨论】:

  • 非常感谢。我还有一个问题。有一个我无法在线解决的错误:logs.push_back({bits[0], bits[1], bits[2], bits[3]});我知道添加新元素需要这一行,但程序只有在我注释时才能编译。
  • 是的,没错,那里的代码是错误的。您不能在函数调用中构建结构“内联”。我通过显式构建结构然后将其添加到向量来修复代码。
  • 我试过这种方式(先把 {} 大括号改成 () ),但还是报错:无法将 'string' 转换为 'vec'。
  • 这是我更改的行:vec v = {bits[0], bits[1], bits[2], bits[3]};,应该可以。
  • 好吧,它不工作,但也许那是因为我使用 borland builder。无论如何,感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多