2014-05-05 5 views
-1

Мой вопрос основан на предыдущем вопросе, который я задал.Использование функции indexof в C++

Multi level hash/dictionary creation in 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 
+4

так в чем ваш вопрос? – Nik

+0

Итак, вам действительно нужно m быть unordered_map >, правильно? – DavidO

+0

@Nik: Мне нужна помощь в кодировании для хранения значений. так что, когда я хочу напечатать «имя», я получаю «abc, cde». – SauShi

ответ

0

Мне кажется, что правильная структура данных для использования является std::unordered_map<std::string,std::vector<std::string>> и неunordered_map<std::string,int>, в качестве тока выполняется попытка реализации. Это потому, что поля, которые вы хотите сохранить, больше похожи на строки; некоторые из них вообще не являются.

Первый шаг - извлечь имена полей, чтобы впоследствии их можно использовать в качестве ключей unordered_map. Затем начните извлечение строк данных, добавив их в поля. Затем, для каждого имени поля, push_back введите данные поля для данной строки 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.

+0

Спасибо за ваш быстрый ответ. Я с нетерпением ждал чего-то подобного. но проблема в том, что я не могу отлаживать программу. Могу ли я помочь мне с этим. благодаря :) – SauShi

Смежные вопросы