Advertisement
gocha

Functions for Loading/Saving RFC4180 CSV

Aug 16th, 2012
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.79 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string>
  3. #include <vector>
  4.  
  5. std::string& string_replace (std::string& str, const std::string& from, const std::string& to)
  6. {
  7.     std::string::size_type pos = 0;
  8.     while (pos = str.find(from, pos), pos != std::string::npos) {
  9.         str.replace(pos, from.length(), to);
  10.         pos += to.length();
  11.     }
  12.     return str;
  13. }
  14.  
  15. std::string csv_escape(const std::string &token)
  16. {
  17.     std::string res(token);
  18.     bool needsQuote = false;
  19.     if (res.find("\"", 0) != std::string::npos) {
  20.         needsQuote = true;
  21.         string_replace(res, "\"", "\"\"");
  22.     }
  23.     if (res.find(",", 0) != std::string::npos ||
  24.         res.find("\n", 0) != std::string::npos) {
  25.         needsQuote = true;
  26.     }
  27.     if (needsQuote) {
  28.         res.insert(0, "\"");
  29.         res.append("\"");
  30.     }
  31.     return res;
  32. }
  33.  
  34.  
  35. std::string csv_unescape(const std::string &token)
  36. {
  37.     std::string res(token);
  38.     if (res.length() >= 2 && res[0] == '\"' && res[res.length() - 1] == '\"') {
  39.         res.erase(res.length() - 1, 1);
  40.         res.erase(0, 1);
  41.     }
  42.     string_replace(res, "\"\"", "\"");
  43.     return res;
  44. }
  45.  
  46. std::vector<std::string> csv_split(const std::string &str, bool *valid = NULL)
  47. {
  48.     std::vector<std::string> res;
  49.  
  50.     if (valid != NULL) {
  51.         *valid = true;
  52.     }
  53.  
  54.     std::string::size_type start = 0;
  55.     std::string::size_type current = 0;
  56.     std::string::size_type found;
  57.     bool insideQuote = false;
  58.     while ((found = str.find_first_of(",\"", current)) != std::string::npos) {
  59.         char c = str[found];
  60.         if (c == '\"') {
  61.             if (insideQuote) {
  62.                 if (str[found + 1] == '\"') {
  63.                     found++; // skip the next quote
  64.                 }
  65.                 else {
  66.                     if (valid != NULL && str[found + 1] != ',' && str[found + 1] != '\0' && str[found + 1] != '\r' && str[found + 1] != '\n') {
  67.                         *valid = false;
  68.                     }
  69.                     insideQuote = false;
  70.                 }
  71.             }
  72.             else {
  73.                 if (valid != NULL && found > 0 && str[found - 1] != ',' && str[found - 1] != '\r' && str[found - 1] != '\n') {
  74.                     *valid = false;
  75.                 }
  76.                 insideQuote = true;
  77.             }
  78.         }
  79.         else if (c == ',') {
  80.             if (!insideQuote) {
  81.                 res.push_back(std::string(str, start, found - start));
  82.                 start = found + 1;
  83.             }
  84.         }
  85.         current = found + 1;
  86.     }
  87.     res.push_back(std::string(str, start, str.size() - start));
  88.  
  89.     if (valid != NULL && insideQuote) {
  90.         *valid = false;
  91.     }
  92.  
  93.     for (int i = 0; i < res.size(); i++) {
  94.         res[i] = csv_unescape(res[i]);
  95.     }
  96.     return res;
  97. }
  98.  
  99. std::string csv_join(std::vector<std::string> &v)
  100. {
  101.     std::string res;
  102.  
  103.     std::vector<std::string>::iterator iter = v.begin();
  104.     bool first = true;
  105.     while(iter != v.end())
  106.     {
  107.         if (first) {
  108.             first = false;
  109.         }
  110.         else {
  111.             res.append(",");
  112.         }
  113.  
  114.         res.append(csv_escape(*iter));
  115.         iter++;
  116.     }
  117.     return res;
  118. }
  119.  
  120. bool ParseCSV(const char *filename)
  121. {
  122.     FILE *fs = fopen(filename, "r");
  123.     char linebuf[1024];
  124.  
  125.     // note: this function do not support fields containing line breaks
  126.     while (fgets(linebuf, 1024, fs) != NULL)
  127.     {
  128.         linebuf[strlen(linebuf) - 1] = '\0';
  129.  
  130.         bool valid = true;
  131.         std::vector<std::string> param = csv_split(std::string(linebuf), &valid);
  132.  
  133.         printf("{ ");
  134.         for (int i = 0; i < param.size(); i++)
  135.         {
  136.             if (i)
  137.                 printf(", ");
  138.             printf("[%d]=%s", i, param[i].c_str());
  139.         }
  140.         printf(" }");
  141.         if (!valid) {
  142.             printf(" // illegal?");
  143.         }
  144.         printf("\n");
  145.     }
  146.     fclose(fs);
  147.     return true;
  148. }
  149.  
  150. int main(int argc, char *argv[])
  151. {
  152.     if (argc < 2) {
  153.         fprintf(stderr, "error: no filename\n");
  154.         return 1;
  155.     }
  156.     printf("return %s;\n", ParseCSV(argv[1]) ? "true" : "false");
  157.    
  158.     //FILE *fs = fopen("saved.csv", "w");
  159.     //if (!fs) return 0;
  160.     //bool enabled = true;
  161.     //std::string code("7E00BE:99+7E00BF:99");
  162.     //std::string name("Money MAX");
  163.     //std::vector<std::string> v;
  164.     //v.push_back(enabled ? "enabled" : "disabled");
  165.     //v.push_back(code);
  166.     //v.push_back(name);
  167.     //fprintf(fs, "%s\n", csv_join(v).c_str());
  168.     //fclose(fs);
  169.    
  170.     return 0;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement