So yeah. HELP

Code:
#include <string>

#ifndef csv_h
#define csv_h

using namespace std;

class csv {
 public:
  csv();
  string* parse(string values);
  int rows(string values);  int columns(string values);
  string compose(string fields[], int values[], int rows);
 private:
};
#endif



Code:
#include "csv.h"

using namespace std;

csv::csv(){
}

csv::string* parse(string values){
  int rows = 0;
  string rowContent[100];
  int cols = 0;
  string colContent[100];
  int found = -1;
  /* We need to figure out how many rows we have in out CSV string and seprate the CSV string into substrings*/
  while(found != string::npos){
    found = values.find("\n",0);
    rowContent[rows] = values.substr(0,found-1);
    values = values.subst(found+1);
    if(found != string::npos)
      rows++;
  }
  found = -1;
  /* Now we need to figure out how many columns we have and seperate the rows into substrings*/
  for(int i=0; i<rows; i++){
    found = rowContent[i].find(",",0);
    columnContent[cols] = rowContent[i].substr(0, found-1);
    rowContent[i] = rowContent[i].substr(found+1);
    if(found != string::npos)
      cols++;
  }
  string ret[rows][cols];
  for(int r=0; r<rows; r++){
    for(int c=0l c<cols; c++){
      ret[r][c]=columnContent[c];
    }
  }
  return ret;
}



Code:
#include <iostream>
#include <string>
#include "csv.h"

using namespace std;

int main(){
  string csvstring="Test, 123\nFun?,HELL NO\nTest is done?,YES";
  csv parser();
  string* values = parser.parse(csvstring);
  for(int r=0; r<values.length(); r++){
    for(int c=0; c<values[r].length(); c++){
      cout << values[r][c] + " ";
    }
    cout << endl; 
  }
  return 0;
}

Edit: Why do I always forget the error?
Edit 2: GRAAAAAAAAAAAAAAA WHY WHY WHY *cries*

Code:
main.cpp: In function ‘int main()’:
main.cpp:10:27: error: request for member ‘parse’ in ‘parser’, which is of non-class type ‘csv()’
main.cpp:11:25: error: request for member ‘length’ in ‘values’, which is of pointer type ‘std::string* {aka std::basic_string<char>*}’ (maybe you meant to use ‘->’ ?)
First off, doing
Code:
csv parser();
may seem right, but it doesn't do what you expect, which is just
Code:
csv parser;
or
Code:
csv parser = csv();
.

For the second error, look at what g++ tells you. Telling you to use -> for a pointer says that you are using a '.' on a pointer. Now, when you have a string*, there are no methods to find the size of the array. You need to return the size of the 2D array. Second, string* does not represent a 2D array, it represents a 1D array. Use string** instead.

Using some sort of STL class (vector<vector<string>>) would simplify this, but would not be the most optimal solution.

Code:
string ret[rows][cols];
...
  return ret;


You can't do this, you can't return a pointer to something allocated on the stack. The compiler may let you, but it'll just cause memory corruption and crashes.

Also if you aren't, make sure when you compile you also use the flags -Wall -Werror. That turns on more warnings, and treats warnings as errors. It may seem annoying, but most of the warnings really are errors.
Ignore the previous stuff. I'm using libcsv now, but gcc won't find it. I'm using the -llibcsv flag, but I'm not entirely sure that's correct...

Code:
#include <iostream>
#include <string>
#include "libcsv/csv.h"

using namespace std;

static int put_comma;

void cb1 (void *s, size_t i, void *p) {
  if (put_comma)
    putc(',', stdout);
  csv_fwrite(stdout, s, i);
  put_comma = 1;
}

void cb2 (int c, void *p) {
  put_comma = 0;
  putc('\n', stdout);
}

int main(){
  string csvstring="Test, 123\nFun?,HELL NO\nTest is done?,YES";
  struct csv_parser p;
  csv_init(&p, 0);
  for(int i=0; i < csvstring.length(); i++){
    if(csv_parse(&p, &c, 1, cb1, cb2, NULL) != 1){
      fprintf(stderr, "Error: %s\n", csv_strerror(csv_error(&p)));
      exit(EXIT_FAILURE);
    }
  }
  csv_fini(&p, cb1, cb2, NULL);
  csv_free(&p);
  return 0;
}
pcb_master wrote:
I'm using the -llibcsv flag, but I'm not entirely sure that's correct...
Just do -lcsv. The 'lib' is implied, so it's actually looking for liblibcsv.so as you have things.
I tried using -lcsv but it still says that libcsv/csv.h can't be found...
Okay, so it compiled with -I /usr/local/include/ but now...

Code:
./csv_test: error while loading shared libraries: libcsv.so.3: cannot open shared object file: No such file or directory


My code (slightly different)

Code:
#include <iostream>
#include <string>
#include <csv.h>

using namespace std;

static int put_comma;

void cb1 (void *s, size_t i, void *p) {
  if (put_comma)
    putc(',', stdout);
  csv_fwrite(stdout, s, i);
  put_comma = 1;
}

void cb2 (int c, void *p) {
  put_comma = 0;
  putc('\n', stdout);
}

int main(){
  string csvstring="Test, 123\nFun?,HELL NO\nTest is done?,YES";
  struct csv_parser p;
  csv_init(&p, 0);
  char c;
  for(int i=0; i < csvstring.length(); i++){
    c = csvstring[0];
    if(csv_parse(&p, &c, 1, cb1, cb2, NULL) != 1){
      fprintf(stderr, "Error: %s\n", csv_strerror(csv_error(&p)));
      exit(EXIT_FAILURE);
    }
  }
  csv_fini(&p, cb1, cb2, NULL);
  csv_free(&p);
  return 0;
}
Make sure the libcsv.so.3 you built is in your library search path.
Looks more like the problem is that the dynamic linker can't find the library, since he said it compiled okay.

Looks like you installed libcsv to /usr/local (default prefix), so try this:
Code:
$ export LD_LIBRARY_PATH=/usr/local
$ ./csv_test

Ideally you'd want to install a libcsv package provided by your distribution, if there is one, because then you're not duplicating libraries with anything else that might use it and it's already in the default paths.
Tari wrote:
Looks more like the problem is that the dynamic linker can't find the library, since he said it compiled okay.

Looks like you installed libcsv to /usr/local (default prefix), so try this:
Code:
$ export LD_LIBRARY_PATH=/usr/local
$ ./csv_test

Ideally you'd want to install a libcsv package provided by your distribution, if there is one, because then you're not duplicating libraries with anything else that might use it and it's already in the default paths.

I added /usr/local/lib to ld.so.conf, is that better or worse? Man pages only tell you so much...
It's a better permanent solution than setting LD_LIBRARY_PATH manually, but not as good as using a distribution package.
Stupid thing segfaults. I dunno why or where, I'll have too look later. For now, I'll just throw my code up here, in case there is a obvious error or something.
Code:
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <fstream>
#include <string>
#include <curl/curl.h>
#include <csv.h>

using namespace std;

static int numfields = 0;
static string fields[3];  //We will only ever have 3 fields so we can statically allocate this array

struct File {
  const char *filename;
  FILE *stream;
};

void cb1 (void *s, size_t i, void *p){
  csv_write(&fields[numfields], i, s, i);
  numfields++;
}
 
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
  struct File *out=(struct File *)stream;
  if(out && !out->stream) {
    /* open file for writing */
    out->stream=fopen(out->filename, "wb");
    if(!out->stream)
      return -1; /* failure, can't open file to write */
  }
  return fwrite(buffer, size, nmemb, out->stream);
}

void cb2(int c, void *p){
  numfields = 0;
  //we are done reading a row of the file
  if(fields[0] == "FILE"){
    CURL *curl;
    CURLcode res;
    const char * URL = fields[1].c_str();
    const char * PATH = fields[2].c_str();
    struct File dl={
      PATH,
      NULL,
    };
    curl_global_init(CURL_GLOBAL_DEFAULT);
   
    curl = curl_easy_init();
    if(curl) {
      curl_easy_setopt(curl, CURLOPT_URL, URL);
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dl);
      res = curl_easy_perform(curl);
      curl_easy_cleanup(curl);
      if(CURLE_OK != res) {
   cout << "Failed to fetch" << fields[2] << " as was instructed.\n";
      }
      else{
   cout << "Fetch of " << fields[2] << " was successful!\n";
      }
    }
    if(dl.stream)
      fclose(dl.stream);
    curl_global_cleanup();
  }
}

void do_update(int i){
  signal(SIGUSR1, do_update);
  cout << "Fetching update...\n";
  //Fetch update files
  CURL *curl;
  CURLcode res;
  struct File update={
    "update.csv",
    NULL
  };
  curl_global_init(CURL_GLOBAL_DEFAULT);
 
  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1/skulls/update.csv");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &update);
    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    if(CURLE_OK != res) {
      cout << "Failed to fetch the update file.\n";
    }
    else{
      cout << "Fetch successful!\n\n";
    }
  }
  if(update.stream)
    fclose(update.stream);
  curl_global_cleanup();
  struct csv_parser p;
  csv_init(&p, 0);
  char c;
  ifstream fs ("update.csv");
  if (fs.is_open())
    {
      string buf((istreambuf_iterator<char>(fs)), istreambuf_iterator<char>());
      for(int i=0; i<buf.length(); i++){
   c = buf[i];
   if(csv_parse(&p, &c, 1, cb1, cb2, NULL) != 1)
     cout << "Error while parsing! " << csv_strerror(csv_error(&p)) << "\n";
      }
      csv_fini(&p,cb1,cb2,NULL);
      fs.close();
    }
  else{
    cout << "failed to open update.csv!\n";
  }
  csv_free(&p);
}

int main(void){
  signal(SIGUSR1, do_update);
  cout << "Skeletor v0.01 started.\n";
  while(1){  //We don't want the daemon to exit, so we create an infinite loop
    sleep(15); //If we don't wait a it before looping, we will be constantly eating up CPU time!
  }
}


EDIT: The program segfaults when curl sets the target URL on line 59.

  1. Compile curl (and everything else) as a debug build
  2. Choose a graphical debugger on your platform of choice
  3. Set a breakpoint before you reach the offending statement, and inspect the variables being passed in. If you don't understand why curl is breaking, step into it and see what it is trying to do with your inputs. If you don't understand why the variables are what they are, set breakpoints earlier and see how they get that way.
  4. Come back here and post if you do all of that and still can't figure it out. We'll be happy to explain C++ language features that you don't understand and help you work out program logic. But please don't ask us to do the grunt work. If we do it, you won't learn anything.
elfprince13 wrote:

  1. Compile curl (and everything else) as a debug build
  2. Choose a graphical debugger on your platform of choice
  3. Set a breakpoint before you reach the offending statement, and inspect the variables being passed in. If you don't understand why curl is breaking, step into it and see what it is trying to do with your inputs. If you don't understand why the variables are what they are, set breakpoints earlier and see how they get that way.
  4. Come back here and post if you do all of that and still can't figure it out. We'll be happy to explain C++ language features that you don't understand and help you work out program logic. But please don't ask us to do the grunt work. If we do it, you won't learn anything.


I said I would run it through GDB later, I just wanted to put the code here in case the error was obvious. To be honest, I really don't understand pointers all that well.
You didn't actually say that, although it may be what you meant. For all I know, "I'll have to look later" could have meant "I'll throw in a lot of print statements".

Tracing program execution is a great way to learn pointers.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement