2
\$\begingroup\$

The requirement is to skip a line beginning from # sign. Basically, we need to treat it as a comment line. The input is given by the user from the keyboard. I will not be reading it from a file. I have a link to the code that i have written so far. In this code, I have used multiple lines to skip a commented line which is in red colored text.

I wanted to know if it could be improved. As in, just one line of code to skip comment line.

Please note: The comment line could be given anywhere from the keyboard.

#include
#include
#include
#include

using namespace std;

unsigned long int m;
unsigned long int n;
int res;
unsigned long int i, j, k, ctr, maxIndex;
long int l,la,lb;
string command, key,comment;
string indexS;
long int index, lo=0, hi,mid;
char key1[500];
char keyd[500];
char keym[500];
char data1[10000][500], maskS[10000][500];
char maskey[10000];
char maskSt[10000][500];
char data[10000][500];

void *runner(void *numbers);
void *runnera(void *numbersa);
void *runnerStar(void *numbers);
void *runnerStara(void *numbersa);
int readKey(string s); /* A function that returns 1 when '*' is found and returns 0 if '*' not found in key*/
void checkKey(string str);
void checkIndex(string strInd);
char StoC(string input);
void mErr(string eKey, unsigned long int mCheck);
long int search(char dataS[10000][500], char keyS[500], unsigned long int mS, unsigned long int nS, unsigned long int initial, unsigned long int final);
long int searchStar(char dataSt[10000][500],char keySt[500], unsigned long int mSt, unsigned long int nSt, unsigned long int initialSt, unsigned long int finalSt);

long int searchA(char dataS[10000][500], char keyS[500], unsigned long int mS, unsigned long int nS, unsigned long int initial, unsigned long int final);
long int searchStarA(char dataSt[10000][500],char keySt[500], unsigned long int mSt, unsigned long int nSt, unsigned long int initialSt, unsigned long int finalSt);

/*---Structure for threads--*/
struct arg_struct {
  char numData[5000][500];
  char numKey[500];
  unsigned long int numM;
  unsigned long int numN;
  unsigned long int numLo;
  unsigned long int numMid;
};

struct arg_structa {
  char numaData[5000][500];
  char numaKey[500];
  unsigned long int numaM;
  unsigned long int numaN;
  unsigned long int numaMid;
  unsigned long int numaHi;
};

int main()
{

  cout << "Enter the command:"<< endl;
  cout << "Enter input  of the form:\n";
    cout << "(a) for insert(i) and replace(r) : i \n";
    cout << "(b) for delete(d)                : d \n";
    cout << "(c) for searching(s)             : s \n";

  cin >> command;
  const char *comnta = command.c_str();

  if(*comnta =='#') { /*Skipping comment line part*/
    cin.clear();
    getline(cin,comment);
    cin>>command;
    const char *comntb = command.c_str();

    if(*comntb =='#') { /*Skipping comment line part*/
      cin.clear();
      getline(cin,comment);
      cin>>command;
    }
    const char *comntc = command.c_str();

    if(*comntc =='#') { /*Skipping comment line part*/
      cin.clear();
      getline(cin,comment);
      cin>>command;
    }
  }

  try {
    if(command == "d") {
      cin >> indexS;
      const char *indexComm = indexS.c_str();

      if(*indexComm == '#') { /*Skipping comment line part*/
    cin.clear();
    getline(cin,comment);
    cin>>indexS;
    index = atoi(indexS.c_str());
    const char *indexComma = indexS.c_str();

    if(*indexComma == '#') { /*Skipping comment line part*/
      index = 0;
      cin.clear();
      getline(cin,comment);
      cin>>indexS;
      index = atoi(indexS.c_str());
    }
      }
      checkIndex(indexS);
      index  = atoi(indexS.c_str());
    }

    else if(command =="s") {
      cin >> key;
      const char *keyComm = key.c_str();

      if(*keyComm == '#') { /*Skipping comment line part*/
    cin.clear();
    getline(cin,comment);
    cin>> key;
    const char *keyComma = key.c_str();

    if(*keyComma == '#') { /*Skipping comment line part*/
      cin.clear();
      getline(cin,comment);
      cin>> key;
    }
      }
      checkKey(key);
    }

    else if(command == "i" || command == "r") {
      cin >> indexS;

      const char *indexCommc = indexS.c_str();
      if(*indexCommc == '#') { /*Skipping comment line part*/
    cin.clear();
    getline(cin,comment);
    cin>>indexS;
    index = atoi(indexS.c_str());
    const char *indexCommd = indexS.c_str();

    if(*indexCommd == '#') {
      index = 0;
      cin.clear();
      getline(cin,comment);
      cin>>indexS;
      index = atoi(indexS.c_str());
    }
      }
      checkIndex(indexS);
      index  = atoi(indexS.c_str());
      ctr = index;

      if(maxIndex < ctr)
    maxIndex = ctr;

      cin >> key;
      const char *keyCommb = key.c_str();

      if(*keyCommb == '#') {
    cin.clear();
    getline(cin,comment);
    cin>> key;
    const char *keyCommc = key.c_str();

    if(*keyCommc == '#') {
      cin.clear();
      getline(cin,comment);
      cin>> key;
    }
      }
      checkKey(key);
    }

    else
      throw(command);  
  }

  catch(string err) {
    cout << "The input must be of the form:\n";
    cout << "(a) for insert(i) and replace(r) : i \n";
    cout << "(b) for delete(d)                : d \n";
    cout << "(c) for searching(s)             : s \n";
    exit(0);
  }

  m = key.size();  /* Bit size of each entry of TCAM*/
  n = 10000;                     /*Number of entries in TCAM*/

  /*--------------------------------------------------------------------------------------*/
  int loop = 0;
  for(;;) {
    cout << "Enter input  of the form:\n";
    cout << "(a) for insert(i) and replace(r) : i \n";
    cout << "(b) for delete(d)                : d \n";
    cout << "(c) for searching(s)             : s \n";
    if(loop == 1) {
      cout << "Enter the command:\n";
      if (!(cin >> command))
    break;
      const char *comntd = command.c_str();
      if(*comntd =='#') {
    cin.clear();
    getline(cin,comment);
    cin>>command;
    const char *comntd = command.c_str();

    if(*comntd =='#') {
      cin.clear();
      getline(cin,comment);
      cin>>command;
    }
    const char *comnte = command.c_str();

    if(*comnte =='#') {
      cin.clear();
      getline(cin,comment);
      cin>>command;
    }
      }

      try {
    if(command == "d")
      {
        cin >> indexS;

        const char *indexCommd = indexS.c_str();
        if(*indexCommd == '#') {
          cin.clear();
          getline(cin,comment);
          cin>>indexS;
          index = atoi(indexS.c_str());
          const char *indexComme = indexS.c_str();

          if(*indexComme == '#') {
        index = 0;
        cin.clear();
        getline(cin,comment);
        cin>>indexS;
        index = atoi(indexS.c_str());
          }
        }
        checkIndex(indexS);
        index  = atoi(indexS.c_str());
      }
    else if(command =="s") {
      cin >> key;
      const char *keyCommd = key.c_str();
      if(*keyCommd == '#') {
        cin.clear();
        getline(cin,comment);
        cin>> key;
        const char *keyComme = key.c_str();
        if(*keyComme == '#') {
          cin.clear();
          getline(cin,comment);
          cin>> key;
        }
      }
      checkKey(key);
      mErr(key, m);
    }

    else if(command == "i" || command == "r") {
      cin >> indexS;
      const char *indexCommf = indexS.c_str();

      if(*indexCommf == '#') {
        cin.clear();
        getline(cin,comment);
        cin>>indexS;
        index = atoi(indexS.c_str());
        const char *indexCommg = indexS.c_str();

        if(*indexCommg == '#') {
          index = 0;
          cin.clear();
          getline(cin,comment);
          cin>>indexS;
          index = atoi(indexS.c_str());
        }
      }
      checkIndex(indexS);
      index  = atoi(indexS.c_str());
      ctr = index;

      if(maxIndex < ctr)
        maxIndex = ctr;

      cin >> key;
      const char *keyCommf = key.c_str();
      if(*keyCommf == '#') {
        cin.clear();
        getline(cin,comment);
        cin>> key;
        const char *keyCommg = key.c_str();

        if(*keyCommg == '#') {
          cin.clear();
          getline(cin,comment);
          cin>> key;
        }
      }
      checkKey(key);
      mErr(key, m);
    }  

    else
      throw(command);
      }

      catch(string err)    {
    cout << "The input must be of the form:\n";
    cout << "(a) for insert(i) and replace(r) : i \n";
    cout << "(b) for delete(d)                : d \n";
    cout << "(c) for searching(s)             : s \n";
    exit(0);
      }
    }
      loop =1;
      /*-------------Without '*' bits in the search key i.e res=0-------------------------------*/
      /*-------------------------------Begin searching part of the code------------------------*/

      readKey(key);

      if(command == "s" && res ==0)
    {
      StoC(key); /* returns key1 which is a char type*/

      pthread_t tid, tida;
      pthread_attr_t attr;
      pthread_attr_init(&attr);

      struct arg_struct args;
      struct arg_structa argsa;
      /*----Spliting up the indices of the TCAM for parallelism-----*/
      lo =0;
      hi =  maxIndex;
      mid = (lo+hi)/2;

      /*-----Assigning values to the data structure-------*/
      for(unsigned long int o=lo; o<=mid; o++)
        for(unsigned long int r=0; r           {
        args.numData[o][r] = data[o][r];
        args.numKey[r] = key1[r];

          }
      for(unsigned long int x=mid+1; x<=hi; x++)
        for(unsigned long int u=0; u           {
               argsa.numaData[x][u] = data[x][u];
               argsa.numaKey[u] = key1[u];

          }

        args.numM = m;
        args.numN = n;
        args.numLo = lo;
        args.numMid = mid;

               argsa.numaM = m;
        argsa.numaN = n;
        argsa.numaMid = mid;
        argsa.numaHi = hi;

        /*----Creating 2 threads to be executed------*/
        pthread_create(&tid, &attr, runner, (void *)&args);
             pthread_create(&tida, &attr, runnera, (void *)&argsa); /* thread for second half of data*/

        /*-------Waiting for both the thrads to complete execution-------*/
        pthread_join(tid, NULL);
        pthread_join(tida, NULL);

        /*------Printing ouput values based on lowest index match----------*/
        if(la ==-1 && lb==-1)
          cout<< la <        
        else if(la == -1 && lb >=0)
          cout<< lb <        
        else if(la >= 0 && lb ==-1)
          cout<< la <        
        else if(la>=0 && lb >=0)
          cout<< la <     }


      /*-----------------Search with '*' bits in the search key---------------------------------------------*/

      else if(command == "s" && res==1)
    {
      StoC(key);

      pthread_t thid, thida;
      pthread_attr_t attr;
      pthread_attr_init(&attr);

      struct arg_struct args;
      struct arg_structa argsa;

      lo =0;
      hi =  maxIndex;
      mid = (lo+hi)/2;

      for(unsigned long int o=lo; o<=mid; o++)
        for(unsigned long int r=0; r           {
        args.numData[o][r] = data[o][r];
        args.numKey[r] = key1[r];
          }
      for(unsigned long int x=mid+1; x<=hi; x++)
        for(unsigned long int u=0; u           {
               argsa.numaData[x][u] = data[x][u];
               argsa.numaKey[u] = key1[u];
          }

      args.numM = m;
      args.numN = n;
      args.numLo = lo;
      args.numMid = mid;

      argsa.numaM = m;
      argsa.numaN = n;
      argsa.numaMid = mid;
      argsa.numaHi = hi;

      /*--------creating thread for program-----------------*/
      pthread_create(&thid, &attr, runnerStar, (void *)&args);
      pthread_create(&thida, &attr, runnerStara, (void *)&argsa); /* thread for second half of data*/

      /*------Wait for both the threads to complete execution--------*/
      pthread_join(thid, NULL);
      pthread_join(thida, NULL);

        /*------Printing ouput values based on lowest index match----------*/
        if(la ==-1 && lb==-1)
          cout<< la <

        else if(la == -1 && lb >=0)
          cout<< lb <

        else if(la >= 0 && lb ==-1)
          cout<< la <

        else if(la>=0 && lb >=0)
          cout<< la <
    }

      /*-------------Inserting data at index-- i key 1011-----dataind[n+1][m]-------------------------*/
      else if(command =="i")
    {
      StoC(key);

      if((data[index][0] == '\0')) {
        for(unsigned long int bit=0; bit           data[index][bit] = key1[bit];
      }
      else {
        unsigned long int g = 0;
        for(g=(index+1);g           if(data[g][0] =='\0')
        break;
        }

        if(maxIndex < g)
          maxIndex = g;

        for( unsigned long int e=g; e>index; e--)
          for(unsigned long int biti=0; biti         data[e][biti] = data[e-1][biti];

        for( unsigned long int bit=0; bit           data[index][bit] = key1[bit];
      }
    }
      /*------------- delete index---------------------------*/
      else if(command =="d")
    {  
      i=0;
      for(i=index; i<=maxIndex;i++)
        for(int bitd=0; bitd           data[i][bitd]= data[i+1][bitd];

      if(maxIndex >= index && maxIndex !=0)
        maxIndex = maxIndex-1;
    }

      /*------------- replace index key---------------------------*/

      else if(command == "r")
    {  
      StoC(key);
      for(unsigned long int bitr=0; bitr         data[index][bitr] = key1[bitr];
    }
       cout<<"\n\n\n";
  cout<<<"tcam table="" entries="" without="" star\n";   // line();
  cout<<<"index"<<<"data"<<<"mask"<
  //line();
  for(unsigned long int k=0;k<=10;k++)
    { 
      cout<<<<<
    }
  //line();
  cout<<<

  }

  return 0;
}

/*----------------------Function definitions begin------------------*/
int readKey(string s)
{
  const char *p = s.c_str();
  while (*p != '\0') {
    if (*p == '*') {
      res = 1;
      return(res);
    }
    else {
      res = 0;
    }
    *p++;
  }
  return(res);
}

/*-------------------------------------------------*/
void checkKey(string str)
{
  const char *p = str.c_str();
  try {
    while (*p != '\0') {
      if(*p=='*' || *p=='0' || *p=='1')
    *p++;
      else
    throw(*p);
    }
  }
  catch( char error) {
    cout <<"ERROR: The input key must be in '1', '0', or '*'" << endl;
    exit(0);
  }    
}
/*-------------------------------------------------*/

void checkIndex(string strInd)
{
  const char *ind = strInd.c_str();
  try {
    while (*ind != '\0') {
      if(*ind=='0'|| *ind=='1'|| *ind=='2'|| *ind=='3'|| *ind =='4'|| *ind=='5'|| *ind=='6'|| *ind=='7'|| *ind=='8'|| *ind=='9')
    *ind++;
      else
    throw(*ind);
    }
  }
  catch( char error) {
    cout <<"ERROR: The input index must be a number" << endl;
    exit(0);
  }
}


/*----------------------------------------------------*/
char StoC(string input)
{
  i = 0; 
  const char *p = input.c_str();
  while (*p != '\0')
    {
      key1[i] = *p;
      i++;
      *p++;   
    }
  return(*key1);
}

 /*-----------------ERROR in key length-------------------------*/

void mErr(string eKey, unsigned long int mCheck)
{
  if(eKey.size() != mCheck) {
    cout<< "ERROR: Key size must not vary"<
    exit(0);
  }
}

/*---------------------------Search without * key-----------------*/

long int search(char dataS[10000][500],char keyS[500], unsigned long int mS, unsigned long int nS, unsigned long int initial, unsigned long int final)
{
  /*---------------------Generating mask of the TCAM entries----------------------------*/

  for(unsigned long int i=initial; i<=final; i++)
    for(unsigned long int j=0; j       if(dataS[i][j] == '*')
    maskS[i][j]='0';
      else
    {
      data1[i][j] = dataS[i][j];
      maskS[i][j] = '1';
    }

  bool flag = true;
  for(la=initial; la<=final; la++) {
    flag = true;
    for(unsigned long int k=0;k       if ( maskS[la][k]== '1') {
    if (keyS[k] != data1[la][k])
      {
        flag = false;
      }
      }
    }
    if (flag)
      {
    return(la);
      }
  }
  la = -1;
  return(la); 
}

/*---------------------------Search without * key2-----------------*/
long int searchA(char dataS[10000][500],char keyS[500], unsigned long int mS, unsigned long int nS, unsigned long int initial, unsigned long int final)
{
  /*---------------------Generating mask of the TCAM entries----------------------------*/
  for(unsigned long int u=initial+1; u<=final; u++)
    for(unsigned long int j=0; j       if(dataS[u][j] == '*')
    maskS[u][j]='0';
      else
    {
      data1[u][j] = dataS[u][j];
      maskS[u][j] = '1';
    }       
  bool flaga = true;
  for(lb=initial+1; lb<=final; lb++) {
    flaga = true;
    for(unsigned long int k=0;k       if ( maskS[lb][k]== '1') {
    if (keyS[k] != data1[lb][k]) {
      flaga = false;
    }
      }
    }
    if (flaga)
      {
    return(lb);
      }
  }

  lb = -1;
  return(lb); 

}
/*------------------------------Search with * key-------------------------------------------------------*/
long int searchStar(char dataSt[10000][500],char keySt[500], unsigned long int mSt, unsigned long int nSt, unsigned long int initialSt, unsigned long int finalSt)
{

  for(unsigned long int a=initialSt; a<=finalSt; a++)
    for(unsigned long int b=0; b       if(dataSt[a][b] == '*') maskSt[a][b]='0';
      else
    {
      data1[a][b] = dataSt[a][b];
      maskSt[a][b] = '1';
    }
  for(unsigned long int j=0;j
    {
      if(keySt[j] =='*')
    keym[j] = '0';
      else
    { 
      keyd[j] = keySt[j];
      keym[j] = '1';
    }
    }
  bool flag = true;
  for( la=initialSt; la<=finalSt; la++) {
    flag = true;
    for(unsigned long int k=0;k       if ( maskSt[la][k]== '1' && keym[k]=='1') {
    if (keyd[k] != data1[la][k]  )
      {
        flag = false;
      }
      }
    }
    if (flag)
      {
    return(la);
      }
  }

  la = -1;
  return(la); 
}
/*---------------------------------------------------------------------------------*/
/*------------------------------Search with * key-------------------------------------------------------*/
long int searchStarA(char dataSt[10000][500],char keySt[500], unsigned long int mSt, unsigned long int nSt, unsigned long int initialSt, unsigned long int finalSt)
{
  for(unsigned long int a=initialSt+1; a<=finalSt; a++)
    for(unsigned long int b=0; b       if(dataSt[a][b] == '*') maskSt[a][b]='0';
      else
    {
      data1[a][b] = dataSt[a][b];
      maskSt[a][b] = '1';
    }


  for(unsigned long int j=0;j
    {
      if(keySt[j] =='*')
    keym[j] = '0';

      else
    { 
      keyd[j] = keySt[j];
      keym[j] = '1';
    }
    }
  bool flaga = true;
  for( lb=initialSt+1; lb<=finalSt; lb++) {
    flaga = true;
    for(unsigned long int k=0;k       if ( maskSt[la][k]== '1' && keym[k]=='1') {
    if (keyd[k] != data1[la][k]  )
      {
        flaga = false;
      }
      }
    }
    if (flaga)
      {
    return(lb);
      }
  }

  lb = -1;
  return(lb); 
}

/*-----------Thread1 function for searching without star key------------------*/
void *runner(void *numbers)
{
  struct arg_struct *args = (struct arg_struct *)numbers;
  search(args-> numData, args-> numKey, args-> numM, args-> numN, args-> numLo, args-> numMid);
  pthread_exit(0);
}

/*-----------Thread2 function for searching without star key------------------*/
void *runnera(void *numbersa)
{
  struct arg_structa *argsa = (struct arg_structa *)numbersa;
  searchA(argsa-> numaData, argsa-> numaKey, argsa-> numaM, argsa-> numaN, argsa-> numaMid, argsa-> numaHi);
  pthread_exit(0);
  }

/*-----------Thread1 function for searching without star key------------------*/
void *runnerStar(void *numbers)
{
  struct arg_struct *args = (struct arg_struct *)numbers;
  searchStar(args-> numData, args-> numKey, args-> numM, args-> numN, args-> numLo, args-> numMid);
  pthread_exit(0);
}

void *runnerStara(void *numbersa)
{
  struct arg_structa *argsa = (struct arg_structa *)numbersa;
  searchStarA(argsa-> numaData, argsa-> numaKey, argsa-> numaM, argsa-> numaN, argsa-> numaMid, argsa-> numaHi);
  pthread_exit(0);
}
\$\endgroup\$
3
  • \$\begingroup\$ This code is a simple tcam simulation \$\endgroup\$ May 13, 2013 at 0:20
  • \$\begingroup\$ Please copy your code here so we may review it... don't link to it. Edit your post question to include it. \$\endgroup\$ May 13, 2013 at 0:53
  • \$\begingroup\$ Added the code.. \$\endgroup\$ May 13, 2013 at 1:23

1 Answer 1

2
\$\begingroup\$

There is far too much code here for me to review all of it. However, this looks like pure C except for std::string and some iostream usage. I don't know how familiar you are with C++ as opposed to C, but I would write many of these functions very, very differently. In just about every function relating to string manipulation, you first convert it to a C-style string, and then use a lot of old constructs. Much of this can be greatly simplified:

int readKey(string s) 
{
    //Lots of C string wrangling
}

can be a one-liner:

bool readKey(const std::string& str)
{
    return str.find('*') != std::string::npos;
}

The function signature has changed a bit. Firstly, don't pass string by value, pass it by reference to const. Secondly, string has a lot of what you're trying to do inbuilt (and for examples later on, if it doesn't, <algorithm> probably does).


checkKey and checkIndex do almost the exact same thing - abstract this out into a single function:

bool checkValid(const std::string& s, const std::string& allowable, 
                const std::string& error)
{
    bool valid = std::all_of(s.begin(), s.end(), 
                   [&allowable](char c) 
                   { return allowable.find(c) != std::string::npos; });            
    if(!valid) {
        std::cerr << error << "\n";
    }
    return valid;
}

Then again checkKey and checkIndex become one liners:

bool checkKey(const std::string& s)
{
    return checkValid(s, "*01", "Error: The input key must be in '1', '0', or '*'");
}

bool checkIndex(const std::string& strInd)
{
    return checkValid(s, "0123456789", "Error: The input key must a number");
}

Using throw and then catch straight after to signal an error looks horrific to me. I'd personally rather return a bool, but you could simply make the function void and call exit again if you really want it to stop.


char StoC(string input) simply copies input into key1. Firstly, this is a buffer overflow just waiting to happen - there is absolutely no checking whether the length of input will overflow key1. Again, more useless C string wrangling. Assigning to global variables (ugh). The function name also leaves a lot to be desired. The previous ones could be improved, but after reading the code, I suppose I can at least sort of understand the names. This function name still makes no sense to me.

Further, this doesn't need to be a function. Why even declare key1 as a char[]? Why not have it as a string and simply use copy assignment: key1 = <some string>?


I don't really want to dig into some of the longer functions. The function names need a lot of work, for example:

void *runner(void *numbers);
void *runnera(void *numbersa);
void *runnerStar(void *numbers);
void *runnerStara(void *numbersa);

I can glean absolutely nothing from those function names. The same can be said with regards to the variable names.

Your main function is far, far too long - it needs to be broken up into more functions. The formatting is haphazard - perhaps this is a consequence of pasting the code here, but the whitespace is all over the place, making it even harder to read (and it's pretty hard to read to start with!).

I realize you're using pthreads which makes things slightly more complicated. However, you can still easily utilize std::string and std::vector properly. Don't use things like:

char data1[10000][500];

Use a std::vector<std::string> instead. It'll be less wasteful, you won't have to preallocate huge arrays to make sure they're always big enough (and there's never, ever any guarantee of that anyway). Both std::string and std::vector have C compatible layouts (if you need to pass the underlying array for std::vector, it's as simple as passing &v[0]).

Basically (and this might sound a bit harsh), if I were given this code and told to maintain it, I would try to figure out exactly what it did. I would then throw everything away and rewrite it all from scratch, because it would probably take me less time than trying to decipher it.

\$\endgroup\$
1
  • \$\begingroup\$ Yes. Ill b making changes as per your suggestions. Thank you. \$\endgroup\$ May 13, 2013 at 4:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.