在c++中使用indexof函数

Using indexof function in C++

本文关键字:indexof 函数 c++      更新时间:2023-10-16

我的这个问题是基于我之前问过的问题。

c++中多级哈希/字典创建

我有这个结构,我需要存储在unordered_map使用indexof函数。我正在使用前面问题中指定的配置文件。我需要将第一行存储为索引,并将随后的值存储为该索引下的数组。

到目前为止,我能做到这一点。

#include <cstdlib.h>
#include <stdafx.h>
#include <string.h>
#include <stdio.h>
#include <unordered_map>
#include <iostream>
#include <string>
using namespace std::tr1;
#define false 0
#define true 1
int main()
{
    unordered_map <std::string, int> m;
    FILE *f;
    char c[255];
    char * pnt;
    f=fopen("Config.csv","r");
    if(f==NULL)
    return 1;
    while(!feof(f))
    {    
        fgets(c, 255, f);  //go to the next line
        pnt = strtok( c, ",");
        while( pnt!= NULL ) 
        {
            //the code for storing the values goes here.
            pnt = strtok( NULL, "," );
        }
    }
    fclose(f);
    return 0;
}

我的CSV文件是这样的----

USN,Name,DOB,Sem,Percentage
111,abc,07/03,3,88
112,cde,18/07,4,77

在我看来,要使用的正确数据结构是std::unordered_map<std::string,std::vector<std::string>>,而不是unordered_map<std::string,int>,因为您当前的实现正在尝试。这是因为你想要存储的字段看起来更像字符串;有些根本不是整型。

第一步是提取字段名,以便它们以后可以用作unordered_map键。然后开始提取数据行,将它们标记为字段。接下来,对于每个字段名,回推给定CSV行的字段数据。下面是一个示例(使用一些c++ 11结构):

#include <string>
#include <iostream>
#include <vector>
#include <unordered_map>
#include <sstream>
std::vector<std::string> split ( std::string );
int main () {
  // Sample data for a self-contained example.
  std::vector<std::string> raw_data {
    "USN,Name,DOB,Sem,Percentage",
    "111,abc,07/03,3,88",
    "112,cde,18/07,4,77"
  };

  // Ordered container for field names, unordered for field vectors.
  auto field_names = split( raw_data[0] );
  std::unordered_map<std::string,std::vector<std::string>> parsed;

  // Store fields as vector elements within our unordered map.
  for( auto it = std::begin(raw_data) + 1; it != std::end(raw_data); ++it ) {
    auto fields = split( *it );
    auto field_it = std::begin(fields);
    for( auto name_it = std::begin(field_names);
         name_it != std::end(field_names);
         ++name_it,
         ++field_it
    ) {
      parsed[*name_it].push_back(*field_it);
    }
  }

  // Dump our data structure to verify it's correct;
  for( auto fn : field_names ) {
    std::cout << fn << "t";
  }
  std::cout << "n";
  for ( size_t ix = 0; ix != parsed[field_names[0]].size(); ++ix ) {
    for( auto fn : field_names ) {
      std::cout << parsed[fn][ix] << "t";
    }
    std::cout << "n";
  }
  std::cout << std::endl;

  return 0;
}

std::vector<std::string> split ( std::string instring ) {
  std::vector<std::string> output;
  std::istringstream iss(instring);
  std::string token;
  while( getline( iss, token, ',' ) ) {
    output.push_back(token);
  }
  return output;
}

在我的示例中,我从包含在名为raw_data的向量中的输入数据开始。在您的示例中,您将从文件中提取数据。所以我正在处理数据结构的构建,因为我假设文件处理不是你问题的核心部分。您应该能够很容易地适应我的示例中的标记化和数据结构的构建。

另外,我知道你正在使用tr1::unordered_map,这可能意味着你没有使用c++ 11。尽管如此,我的c++ 11-isms实际上只是利用语法糖,您可以将其降级为等效的c++ 03兼容性,而无需太多工作。

注意,这是一种相对简单的CSV解析方法。它所做的假设可能适用于您的CSV数据,但可能不适用于所有形式的CSV。例如,它不处理字段的引号以允许字段内嵌入逗号。它也不处理反斜杠转义的逗号,也不处理许多其他CSV解析挑战。

如果您的数据集的表现不如这个解析器所能处理的那么好,那么您就应该寻找一个成熟的CSV解析库,而不是摆弄自己的解析器. ...至少,如果我的任务是解析不那么琐碎的CSV格式,我就会这样做。