how to use switch case to take a string parameter? - string

How do I take string input as a switch case parameter? I am able to do it with an int but not string.
The below code would be working if I was using an int input, but if I change to string it won't work.
#include <iostream>
#include <sstream>
#include <string>
#include <math.h>
class MissionPlan //start of MissionPlan class
{
public:
MissionPlan();
float computeCivIndex(string,int,int,float,float);
}; //end of MissionPlan class
LocationData::LocationData()
{
switch(sunType)
{
case "Type A": //compute
break;
case "Type B": //compute
break;
//and many more case..
default: break;
}
}
int main()
{
for(;;)
{
MissionPlan plan;
}
return 0;
}

You cannot use a switch statement on a string in C++, sorry. You're best bet here is to use an enum. If you don't want to use an enum, then your only other option would be to do a bunch of if elses that check the strings for equality.

C/C++ doesn't support switch statements with strings. Use if-else-if instead:
if (sunType.compare("Type A") == 0) {
//compute
} else if (sunType.compare("Type B") == 0) {
// compute
} else {
// default
}

Related

C++ console application async accepting user input

I recently stumbled upon this
link and I just tried it, but it's not working as I expect.
With this code:
#include <atomic>
#include <thread>
#include <iostream>
void ReadCin(std::atomic<bool>& run)
{
std::string buffer;
while (run.load())
{
std::cin >> buffer;
if (buffer == "q")
{
run.store(false);
}
}
}
int main()
{
std::atomic<bool> run(true);
std::thread cinThread(ReadCin, std::ref(run));
while (run.load())
{
// some lengthy operation
}
run.store(false);
cinThread.join();
return 0;
}
In the main While loop, I have an object of a class that is doing some lengthy operation, one which I'm trying to stop with the letter "q" coming from the user. When I type "q", i see the "run.store(false);" hit in the ReadCin method, but this doesn't break me off from the main while loop. What am I doing wrong?

Obtaining signal names in the design (using VPI calls)

I would like to get a list of signal names in a given design hierarchy from a Verilog design using vpi. It is a simple net name browser interface from my custom tool that is written in C and Python.
How can I get a list of signal names from a Verilog design and which VPI calls I should use to walk through the design?
Any info would be greatly appreciated.
In addition to the answer already given this code walk through your hierarchy and store design object of type vpiLogic you can adapt it to your needs.
It stores the full names of the register in an unordered_map which has nice O(1) access time during simulation.
This code was developed for projects using both verilog and VHDL.
You'll also find that sometimes some IP's are protected which is handled gracefully, in addition the usage of scopes (vpiInternalScope) instead of vpiModule allows recursion inside generate statements.
It is c++ code but usage of extern "C" makes it callable from your EDA tools (tested using IUS).
#include "vhpi_user.h"
#include "vpi_user.h"
#include "vpi_user_cds.h"
#include "sv_vpi_user.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unordered_map>
extern "C" {
static std::unordered_map<int , std::string> reg_map;
#define check_verilog(scopeH) (vpi_get(vpiLanguage,scopeH) == vpiVerilog)
#define check_is_protected(scopeH) (vpi_get(vpiIsProtected,scopeH))
#define check_protected(scopeH) (vpi_get(vpiProtected,scopeH))
#define check_vhdl(scopeH) (vpi_get(vpiLanguage,scopeH) == vpiVHDL)
bool is_vpi_protected(vpiHandle scopeH) {
switch(vpi_get(vpiType, scopeH)) {
case vpiClockingBlock:
case vpiNamedBegin:
case vpiTask:
return check_is_protected(scopeH);
default: {
return check_protected(scopeH);
}
}
}
bool is_valid_scope(vpiHandle scopeH) {
switch (vpi_get(vpiType, scopeH)) {
case vpiInstance:
case vpiModule:
case vpiGenScope:
case vpiGenScopeArray:
case vpiInstanceArray:
return true;
default:
return false;
}
}
void vpi_get_reg(vpiHandle module) {
vpiHandle itr_reg, reg;
if ((itr_reg = vpi_iterate(vpiReg,module))) {
while ((reg = vpi_scan(itr_reg))) {
std::string reg_name(vpi_get_str(vpiFullLSName, reg));
vpi_printf("** Verilog register Full Name:\t%s[%d]\n",reg_name.c_str(),vpi_get(vpiSize, reg));
reg_map[(int)reg_map.size()+1] = reg_name;
}
}
}
void vhpi_get_reg(vpiHandle module) {
vhpiHandleT itr_reg, reg;
if (vhpi_get(vhpiKindP,module) == vhpiCompInstStmtK) {
if ((itr_reg = vhpi_iterator(vhpiSigDecls,module))) {
while (reg = vhpi_scan(itr_reg)) {
std::string reg_name(vhpi_get_str(vhpiFullLSNameP, reg));
vhpi_printf("** VHDL register Full LS Name:\t%s[%d]\n",reg_name.c_str(),vhpi_get(vhpiSizeP, reg));
reg_map[(int)reg_map.size()+1] = reg_name;
}
}
}
}
void walk_down(vpiHandle parentScope) {
vpiHandle subScopeI, subScopeH;
if (check_verilog(parentScope) && is_valid_scope(parentScope)) {
vpi_get_reg(parentScope);
if ((subScopeI = vpi_iterate(vpiInternalScope, parentScope))) {
while ((subScopeH = vpi_scan(subScopeI))) {
if (is_vpi_protected(subScopeH)) {
if (vpi_get(vpiType, parentScope)!= vpiGenScope)
vpi_printf("** Verilog scope %s in %s is protected \n",vpi_get_str(vpiFullLSName, subScopeH),vpi_get_str(vpiDefFile,parentScope));
else
vpi_printf("** Verilog scope %s in %s is protected \n",vpi_get_str(vpiFullLSName, subScopeH),vpi_get_str(vpiFile,subScopeH));
}
else {
walk_down(subScopeH);
}
}
}
}
else if(check_vhdl(parentScope)) {
vhpi_get_reg(parentScope);
subScopeI = vhpi_iterator(vhpiInternalRegions, parentScope);
if (subScopeI) {
while ((subScopeH = vhpi_scan(subScopeI)))
walk_down(subScopeH);
}
}
}
void navigate_mixed(const char * scope) {
reg_map.clear();
vpiHandle topScopeI, topScopeH;
vpi_printf(".........Starting register discovery \n");
if ((topScopeH = vpi_handle_by_name((PLI_BYTE8 *)scope, NULL))) {
topScopeI = vpi_iterate(vpiModule, topScopeH);
while ((topScopeH = vpi_scan(topScopeI)))
walk_down(topScopeH);
}
if ((topScopeH = vhpi_handle_by_name((PLI_BYTE8 *)scope, NULL)))
walk_down(topScopeH);
vpi_printf("Completed register discovery........\n");
}
}

Good way to tokenize line from file without using external libraries?

I am trying to tokenize a database dump separated by commas. I only need to read the first word, which will tell me if this is the line I need and then tokenize the line and save each separated string in a vector.
I have had trouble keeping all of the datatypes in order. I use a method of getline:
string line;
vector<string> tokens;
// Iterate through each line of the file
while( getline( file, line ) )
{
// Here is where i want to tokenize. strtok however uses a character array and not a string.
}
The thing is, I only want to continue reading and tokenize a line if the first word is what I am after. Here is a sample of a line from the file:
example,1,200,200,220,10,550,550,550,0,100,0,-84,255
So, if I am after the string example, it goes ahead and tokenizes the rest of the line for my use and then stops reading from the file.
Should I be using strtok, stringstream or something else?
Thank you!
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void do(ifstream& file) {
string line;
string prefix = "example,";
// Get all lines from the file
while (getline(file,line).good()) {
// Compare the beginning for your prefix
if (line.compare(0, prefix.size(), prefix) == 0) {
// Homemade tokenization
vector<string> tokens;
int oldpos = 0;
int pos;
while ((pos = line.find(',', oldpos)) != string::npos) {
tokens.push_back(line.substr(oldpos, pos-oldpos));
oldpos = pos + 1;
}
tokens.push_back(line.substr(oldpos)); // don't forget the last bit
// And here you are!
}
}
}
How do I tokenize a string in C++?
http://www.daniweb.com/software-development/cpp/threads/27905
Hope this helps, though I am not proficient C/C++ programmer. For the record it would be nice if you could specify in the tags or in post language you are using.
Tokenizer.h
#ifndef TOKENIZER_H
#define TOKENIZER_H
#include <string>
#include <vector>
#include <sstream>
class Tokenizer
{
public:
Tokenizer();
~Tokenizer();
void Tokenize(std::string& str, std::vector<std::string>& tokens);
};
#endif /* TOKENIZER_H */
Tokenizer.cpp
#include "Tokenizer.h"
using namespace std;
string seps(string& s) {
if (!s.size()) return "";
stringstream ss;
ss << s[0];
for (int i = 1; i < s.size(); i++)
ss << '|' << s[i];
return ss.str();
}
void tok(string& str, vector<string>& tokens, const string& delimiters = ",")
{
seps(str);
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
Tokenizer::Tokenizer()
{
}
void Tokenizer::Tokenize(string& str, vector<string>& tokens)
{
tok(seps(str), tokens);
}
Tokenizer::~Tokenizer()
{
}
To tokenize a string
#include "Tokenizer.h"
#include <string>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
// Required variables for later below
vector<string> t;
string s = "This is one string,This is another,And this is another one aswell.";
// What you need to include:
Tokenizer tokenizer;
tokenizer.Tokenize(s, t); // s = a string to tokenize, t = vector to store tokens
// Below is just to show the tokens in the vector<string> (c++11+)
for (auto c : t)
cout << c << endl;
system("pause");
return 0;
}

reason for one or more multiply defined symbols found error?

here is my code: why does the error "one or more multiply defined symbols found?"
#include <stdio.h>
#include "person.h"
void main() {
FILE* census;
int status;
int data_read;
person student[10];
census = fopen("mycensus.dat","r");
if (census == NULL) {
printf("File not opened!");
}
else{
data_read = fread(student, sizeof(person), 10, census);
if (data_read != 10) {
printf("Not all data was read from file!");
}
}
}
Most likely, this has something to do with what's being included in person.h.

split a string using find_if

I found the following code in the book "Accelerated C++" (Chapter 6.1.1), but I can't compile it. The problem is with the find_if lines. I have the necessary includes (vector, string, algorithm, cctype). Any idea?
Thanks, Jabba
bool space(char c) {
return isspace(c);
}
bool not_space(char c) {
return !isspace(c);
}
vector<string> split_v3(const string& str)
{
typedef string::const_iterator iter;
vector<string> ret;
iter i, j;
i = str.begin();
while (i != str.end())
{
// ignore leading blanks
i = find_if(i, str.end(), not_space);
// find end of next word
j = find_if(i, str.end(), space);
// copy the characters in [i, j)
if (i != str.end()) {
ret.push_back(string(i, j));
}
i = j;
}
return ret;
}
Writing this in a more STL-like manner,
#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
using namespace std;
template<class P, class T>
void split(const string &str, P pred, T output) {
for (string::const_iterator i, j = str.begin(), str_end = str.end();
(i = find_if(j, str_end, not1(pred))) != str_end;)
*output++ = string(i, j = find_if(i, str_end, pred));
}
int main() {
string input;
while (cin >> input) {
vector<string> words;
split(input, ptr_fun(::isspace), inserter(words, words.begin()));
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
}
return 0;
}
There is no problem in the code you posted. There is a very obvious problem with the real code you linked to: is_space and space are member functions, and they cannot be called without an instance of Split2. This requirement doesn't make sense, though, so at least you should make those functions static.
(Actually it doesn't make much sense for split_v3 to be a member function either. What does having a class called Split2 achieve over having just a free function - possibly in a namespace?)
As requested:
class SplitV2 {
public:
void foo();
private:
struct space { bool operator() (char c) { return isspace(c); } };
struct not_space {
Split2::space space;
bool operator() (char c) { return !space(c); }
};
Use them with std::find_if(it, it2, space()) or std::find_if(it, it2, not_space().
Notice that not_space has a default constructed space as a member variable. It may be not wise to construct space in every call to bool not_space::operator() but maybe the compiler could take care of this. If the syntax for overloading operator() confuses you and you would like to know more about using structs as Predicates you should have a look at operator overloading and some guidelines to the STL.
Off hand, I would say it should probably be
i = str.find_if( ...
j = str.find_if( ...

Resources