How can my code react to unexpected inputs in c++? - c++

Newbe so please don't be to harsh, I'll try to explain my problem as well as possible.
I have a longer code, that receives 0, 1, or n, arguments as input.
These inputs are supposed to be strings, however if I run my program like this:
./task2 ^!..;:
I simply get:
bash: !..: event not found
how can I prevent this error, and just print an error message?
This is task2.cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <array>
#include <functional>
#include <math.h>
#include <stdint.h>
using namespace std;
/// Build suffix array from text.
/// Input is an emtpy suffix array and the text.
/// Output is a suffix array (sorted).
void construct(std::vector<uint32_t>& sa, const std::string& text)
{
if(text.empty()) {
cout << "Text is empty" << endl;
return;
}
if (sa.size()!=0) {
sa.clear();
}
for (uint32_t a = 0; a<text.length(); ++a) {
sa.push_back(a);
}
sort(sa.begin(),sa.end(),[&text] (uint32_t s1, uint32_t s2) {
return(text.substr(s1)<=text.substr(s2));
});
return;
}
//Wir brauchen kein $ am Ende unseres Strings, da wir keinen Suffixbaum aufbauen und wir somit nicht das Problem haben
//werden, dass ein Suffix ein Prefix eines aderen Suffix ist.
/// search for a 'query' string in a suffix array 'sa' build from 'text'.
/// Results are returned in 'hits'.
void findmlr(uint32_t& mlr, const uint32_t L, const uint32_t R, const std::string& query, const std::vector<uint32_t>& sa, const std::string& text) {
uint32_t mlrl = mlr;
uint32_t mlrr = mlr;
/* for L */
for(uint32_t l = mlr; l<query.size(); ++l) {
if (query[mlr] == text[sa[L]+mlrl]) {
mlrl+=1;
}
else{
break;
}
}
/* for R */
for(uint32_t r = mlr; r<query.size(); ++r) {
//cout << query[mlr] << text[sa[R]+mlrr] << endl;
if (query[mlr] == text[sa[R]+mlrr]) {
mlrr+=1;
}
else{
break;
}
}
mlr = min(mlrl,mlrr);
return;
}
void find(std::vector<uint32_t>& hits, const std::string& query, const std::vector<uint32_t>& sa, const std::string& text){
if(hits.size()!=0) {
hits.clear();
}
if (cin.fail()) {
cin.clear();
cout << "unexpected input" << endl;
}
if (text.size()==0) {
cout << "text is empty";
return;
}
else if (query.size()==0) {
cout << "query is empty";
return;
}
/* finding Lp */
uint32_t Lp;
if (query <= text.substr(sa[0])){
Lp = 0;
}
else if (query > text.substr(sa[text.length()-1])){
Lp = text.length();
}
else {
uint32_t L = 0;
uint32_t R = text.length()-1;
uint32_t mlr = 0;
while (R-L > 1) {
uint32_t M = ceil((L+R)/2);
findmlr(mlr,L,R,query,sa,text);
if (query.substr(mlr) <= (text.substr(sa[M]+mlr))) {
R = M;
}
else {
L = M;
}
}
Lp = R;
}
for (uint32_t i = Lp; i < text.length(); ++i) {
if ((text.substr(sa[i])).substr(0,query.length()) == query) {
if(find(hits.begin(), hits.end(), sa[i]) != hits.end()){
//do nothing
}
else{
hits.push_back(sa[i]);
}
}
else {
break;
}
}
sort(hits.begin(), hits.end());
return;
}
and this is task2_main.cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include "aufgabe2.hpp"
#include <stdint.h>
//#include <typeinfo>
using namespace std;
int main(int argc, char* argv[]){
if (argc < 2){
cout << "not enough arguments were given" << endl;
return 1;}
if (argc == 2){
vector<uint32_t> sa;
string input_string(argv[1]);
construct(sa,input_string);
for(uint32_t i = 0; i<input_string.length(); ++i) {
cout << sa[i] << endl;
}
return 0;
}
if (argc > 2){
vector<uint32_t> hits;
string text(argv[1]);
vector<uint32_t> sa;
if (sa.size() != 0) {
sa.clear();
}
if (hits.size() != 0) {
hits.clear();
}
int z;
z = 2;
while(z < argc){
/*
if(typeid(argv[z])!=typeid(text)) {
cout << typeid(text).name() << z << " is not of type string" << endl;
}
*/
if (sa.size()!=0) {
sa.clear();
}
for (int unsigned a = 0; a<text.length(); ++a)
{
sa.push_back(a);
}
sort(sa.begin(),sa.end(),[&text] (uint32_t s1, uint32_t s2) {
return(text.substr(s1)<=text.substr(s2));
});
string query(argv[z]);
string input_string(argv[1]);
if (query.size() == 0) {
//do nothing
}
else if (input_string.size() == 0) {
//do nothing
}
else {
cout << (argv[z]) << ":";
}
find(hits,query,sa,input_string);
for (uint32_t i = 0; i < hits.size(); ++i) {
cout << " " << hits[i];
}
cout << endl;
++z;
}
}
return 0;
}

"Bash event not found" is completely external to your program; GNU Bash has a (mis)feature whereby it reacts to the ! character in a command line, even if that character is in a double-quote.
$ echo "blah!blah!"
bash: !blah!: event not found
$ echo 'blah!blah!'
blah!blah!
Note that in the first case, echo is not even called; Bash failed to process the command line as such, and echo was never invoked. If you see this message, your program is not being called at all and so the situation doesn't speak to how your program handles any kind of input.
You have to escape the ! with single quotes or a backslash. What Bash is trying to do here is to look for blah in the command history for a command which begins with blah and substitute it. This is "history expansion".
The feature is fully described under HISTORY EXPANSION in the Bash manual page.

Related

Memory Heap and Leak Summary on Valgrind

Our school submissions are all through matrix using valgrind, which checks the output line by line. However, when submitting, I'm getting "Memory Error Detected".
Compile result:
Success! No errors or warnings...
Execution:
Script started, file is student_output.txt
Script started, file is student_output.txt
==110143== Memcheck, a memory error detector
==110143== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==110143== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==110143== Command: ms
==110143==
Loading Data
Library Application:
When inputing data:
Publication Title: e
==111103== Conditional jump or move depends on uninitialised value(s)
==111103== at 0x404318: sdds::LibApp::search(int, char) (LibApp.cpp:145)
==111103== by 0x404ABC: sdds::LibApp::removePublication() (LibApp.cpp:329)
==111103== by 0x404DC1: sdds::LibApp::run() (LibApp.cpp:415)
==111103== by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==111103== by 0x405084: main (LibAppMain_prof.cpp:20)
==111103==
Other information
I also get error while adding a publication, (using the newPublication() function), which in the same file below.
==140314== Use of uninitialised value of size 8
==140314== at 0x404926: sdds::LibApp::newPublication() (LibApp.cpp:282)
==140314== by 0x404DAA: sdds::LibApp::run() (LibApp.cpp:411)
==140314== by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==140314== by 0x405084: main (LibAppMain_prof.cpp:20)
==140314==
==140314== Use of uninitialised value of size 8
==140314== at 0x40493F: sdds::LibApp::newPublication() (LibApp.cpp:284)
==140314== by 0x404DAA: sdds::LibApp::run() (LibApp.cpp:411)
==140314== by 0x404F6F: runLibApp(char const*) (LibAppMain_prof.cpp:9)
==140314== by 0x405084: main (LibAppMain_prof.cpp:20)
==140314==
The file is posted below.
LibApp.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <fstream>
#include <cstring>
#include <iomanip>
#include "LibApp.h"
#include "Book.h"
#include "PublicationSelector.h"
namespace sdds {
int NOLP=0;
int LLRN=0;
bool LibApp::confirm(const char* message)
{
Menu conf(message);
conf<<"Yes";
int t_return = conf.run();
if(t_return) return true;
return false;
}
LibApp::LibApp(const char filename[256])
{
m_mainMenu << "Add New Publication"
<< "Remove Publication"
<< "Checkout publication from library"
<<"Return publication to library";
m_exitMenu << "Save changes and exit" << "Cancel and go back to the main menu";
strcpy(m_filename, filename);
m_publicationMenu << "Book" << "Publication" ;
load();
}
LibApp::~LibApp()
{
for (int i = 0; i< NOLP ; i++) {
delete PPA[i];
}
}
void LibApp::load(){
std::cout<<"Loading Data\n";
std::ifstream infile(m_filename);
char type{};
for (int i = 0; infile ; i++) {
infile >> type;
infile.ignore();
if (infile) {
if (type == 'P')
PPA[i] = new Publication;
else if (type == 'B')
PPA[i] = new Book;
else std::cout<<"no data\n";
if (PPA[i] && i < SDDS_LIBRARY_CAPACITY ) {
infile >> *PPA[i];
LLRN=PPA[i]->getRef();
NOLP++;
}
}
}
}
void LibApp::save(){
std::cout<<"Saving Data\n";
std::ofstream outfile(m_filename);
for (int i = 0; i < NOLP; i++) {
if (PPA[i]->getRef()!=0) {
outfile << *PPA[i] << std::endl;
}
}
}
void prnPub(Publication* p[], int size, int ref) {
int i;
for (i = 0; i < size; i++) {
if (ref == p[i]->getRef()) {
std::cout << *p[i] << std::endl;
i = size;
}
}
}
int LibApp::search(int option,char type){
PublicationSelector ps("Select one of the following found matches:", 15);
std::cout<<"Publication Title: ";
char title[256];
std::cin.getline(title,256);
if(option==1)
{
for (int i = 0; i< NOLP; i++) {
if (strstr(*PPA[i],title) && PPA[i]->getRef()!=0 && type==PPA[i]->type())
ps << PPA[i];
}
}
else if(option==2)
{
for (int i = 0; i< NOLP; i++) {
if (strstr(*PPA[i],title) && !PPA[i]->onLoan() && PPA[i]->getRef()!=0 && type==PPA[i]->type())
ps << PPA[i];
}
}
else if(option==3)
{
for (int i = 0; i< NOLP; i++) {
if (strstr(*PPA[i],title) && PPA[i]->onLoan() && PPA[i]->getRef()!=0 && type==PPA[i]->type())
ps << PPA[i];
}
}
int ref = 0;
if (ps) {
ps.sort();
ref = ps.run();
if (ref) {
prnPub(PPA, NOLP , ref);
}
else {
std::cout << "Aborted!\n";
}
}
else {
std::cout << "No matches to found!" << std::endl;
}
return ref;
}
void LibApp::returnPub()
{
std::cout<<"Return publication to the library\n";
int i=m_publicationMenu.run();
char type;
if(i==1) type='B';
else type='P';
int ref=search(3,type);
if(ref!=0 && confirm("Returning publication?"))
{
Date date=getPub(ref)->checkoutDate();
Date today;
int days=today-date;
days-=15;
if(days>0)
{
std::cout << std::fixed;
std::cout << std::setprecision(2);
std::cout<<"Please pay $"<<float(days)*(0.5)<<" penalty for being "<<days<<" days late!\n";
}
getPub(ref)->set(0);
std::cout<<"Publication returned\n";
m_changed=true;
}
}
void LibApp::newPublication()
{
if( NOLP >= SDDS_LIBRARY_CAPACITY )
{
std::cout<<"Library is at its maximum capacity!\n";
return;
}
std::cout<<"Adding new publication to library\n";
int i=m_publicationMenu.run();
Publication *p=nullptr;
if(i==0)
{ std::cout<<"Aborted!\n";
return;
}
else if(i==1)
{
p = new Book;
std::cin >> *p;
}
else if( i==2 )
{
p = new Publication;
std::cin >> *p;
}
if(std::cin.fail())
{
std::cout<<"\nAborted!\n";
exit(0);
}
if(confirm("Add this publication to library?"))
{
m_changed = true;
PPA[NOLP]=p;
LLRN=PPA[NOLP]->getRef();
NOLP++;
std::cout<<"Publication added\n";
}
if( !*p )
{
std::cout<<"Failed to add publication!\n";
delete p;
}
}
Publication* LibApp::getPub(int libRef)
{
for(int i=0;i<NOLP;i++)
{
if(libRef==PPA[i]->getRef()) return PPA[i];
}
return nullptr;
}
void LibApp::removePublication()
{
//std::cout<<;
std::cout<<"Removing publication from the library\n";
int i=m_publicationMenu.run();
char type;
if(i==1) type='B';
else
{
type='P';
}
int ref=search(1,type);
if(ref!=0 && confirm("Remove this publication from the library?"))
{
m_changed = true;
getPub(ref)->setRef(0);
std::cout<<"Publication removed\n";
}
}
void LibApp::checkOutPub()
{
std::cout<<"Checkout publication from the library\n";
int i=m_publicationMenu.run();
char type;
if(i==1) type='B';
else type='P';
int ref=search(2,type);
if(ref!=0 && confirm("Check out publication?"))
{
m_changed = true;
int mn;
std::cout << "Enter Membership Number: ";
while (1)
{
std::cin>>mn;
if(mn > 9999 && mn <= 99999 ) break;
std::cout<<"Invalid membership number, try again: ";
}
getPub(ref)->set(mn);
std::cout<<"Publication checked out\n";
}
}
LibApp::LibApp()
{
m_mainMenu << "Add New Publication"
<< "Remove Publication"
<< "Checkout publication from library"
<<"Return publication to library";
m_exitMenu << "Save changes and exit" << "Cancel and go back to the main menu";
load();
}
void LibApp::run()
{
while(1)
{
int option = m_mainMenu.run();
if( option == 1 )
{
newPublication();
}
else if( option == 2 )
{
removePublication();
}
else if( option == 3 )
{
checkOutPub();
}
else if( option == 4 )
{
returnPub();
}
else if( option == 0 )
{
if(m_changed)
{
int opn = m_exitMenu.run();
if( opn == 1 )
{
save();
break;
}
else if( opn == 2 )
{
;
}
else if( opn == 0)
{
if(confirm("This will discard all the changes are you sure?"))
break;
}
}
else break;
}
std::cout<<std::endl;
}
std::cout<<std::endl;
std::cout<<"-------------------------------------------\n";
std::cout<<"Thanks for using Seneca Library Application\n";
}
}
Please help me with this. My submission is today idk what the issues are.
Like the error message says:
Conditional jump or move depends on uninitialised value(s)
==111103== at 0x404318: sdds::LibApp::search(int, char) (LibApp.cpp:145)
There is an if-statement (or something logically equivalent to an if-statement) at line 145 of LibApp.cpp that is basing its decision on which path to take on a variable that was never initialized to any value; as such, the behavior of that if-test is undefined (ie if could go either way depending on what arbitrary data happens to be present at that variable’s memory location at the time).
So you’ll need to look at the variable(s) present in the if-test at line 145 to figure out which ones aren’t being set beforehand, and then fix the error by making sure they do get set first.
If necessary, you can add temporary if-tests just to provoke valgrind into giving you more results:
if (some_suspect_var != 0) fprintf(stderr, “Yea\n”);
else fprintf(stderr, “Nay\n”);
… then if you get a valgrind error on that if-line, you know that some_suspect_var is uninitialized at that point.

Unknown Type Name when using threads

I am trying to find the minimum vertex cover by giving the vertex and edge input in specific format from the user using threads. Here is my code:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cctype>
#include <list>
#include <set>
#include <vector>
#include <climits>
#include <memory>
#include <algorithm>
#include <pthread.h>
#include <unistd.h>
#include "minisat/core/Solver.h"
using namespace std;
static void *AVC2_Vertex_Cover(void *);
void min_vertex_cover_algorithm(Graph &graph_builder){
int ret;
pthread_t AVC2_thread;
ret = pthread_create(&AVC2_thread, NULL, AVC2_Vertex_Cover, &graph_builder);
if(ret)
exit(1);
pthread_join(AVC2_thread, NULL);
pthread_exit(NULL);
}
struct Edge{
unsigned v1,v2;
};
typedef std::vector<unsigned> Vertex_vector;
typedef std::list<unsigned > Vertex_Adjacency_list;
typedef std::vector<Vertex_Adjacency_list> Adjacency_Traversal_list;
struct Graph{
std::size_t no_of_edges;
Adjacency_Traversal_list adjacency_list;
void initialize_graph(unsigned vertices_number);
void construct_edge(Edge edge);
void clear(unsigned vertex);
};
void Graph::initialize_graph(unsigned num){
adjacency_list.clear();
no_of_edges = 0;
adjacency_list.resize(num,{});
}
void Graph::construct_edge(Edge edge) {
auto &literal_1 = adjacency_list[edge.v1];
auto &literal_2 = adjacency_list[edge.v2];
literal_1.push_back(edge.v2);
literal_2.push_back(edge.v1);
no_of_edges ++;
}
void *AVC2_Vertex_Cover(void *input)
{
Graph g = *(const Graph *)input;
unsigned int V = g.adjacency_list.size();
bool visited[V];
for (int i=0; i<V; i++)
visited[i] = false;
for (int u=0; u<V; u++)
{
if (visited[u] == false)
{
for(int x : g.adjacency_list[u])
{
int v = x;
if (visited[v] == false)
{
visited[v] = true;
visited[u] = true;
break;
}
}
}
}
// Print the vertex cover
std::cout << "APPROX-VC-2: ";
for (int i=0; i<V; i++){
if (visited[i])
if(i == V-1)
cout << i << std::endl;
else
cout << i << ",";
}
}
void *IO_thread(void *)
{
Graph &graph_builder = *new Graph();
char character_input;
string my_input;
unsigned int no_of_vertices = 0;
string edge_stream;
char prev_choice = ' ';
while (getline(cin, my_input))
{
istringstream stream_string(my_input);
while (stream_string >> character_input)
{
character_input=(toupper(character_input));
try
{
switch (character_input)
{
case 'V' :
if (prev_choice == 'V')
{
cerr << "Error: V must be followed by E only.\n";
break;
}
else
{
stream_string >> no_of_vertices;
if(no_of_vertices <= 0)
{
throw "Invalid number of vertices";
}
graph_builder.initialize_graph(no_of_vertices);
prev_choice = 'V';
break;
}
case 'E' :
{
unsigned int flag_Entry = 0;
if ( prev_choice == 'E')
{
cerr << "Error: V and E always occur together.\n ";
break;
}
else
{
stream_string >> edge_stream;
istringstream edge_stream_character(edge_stream);
char edg_char;
unsigned int temp = 0;
unsigned int v1;
unsigned int v2;
edge_stream_character >> edg_char;
while (edg_char != '}')
{
edge_stream_character >> edg_char;
if (edg_char == '}')
{
flag_Entry = 1;
break;
}
else
{
edge_stream_character >> temp;
v1 = temp;
edge_stream_character >> edg_char;
edge_stream_character >> temp;
v2 = temp;
edge_stream_character >> edg_char;
edge_stream_character >> edg_char;
if (v1 >= no_of_vertices || v2 >= no_of_vertices)
{
cerr << "Error: Vertex out of range.\n";
graph_builder.adjacency_list.clear();
break;
}
graph_builder.construct_edge({v1,v2});
}
}
if(flag_Entry == 1)
{
prev_choice = 'E';
break;
}
min_vertex_cover_algorithm(graph_builder);
prev_choice = 'E';
break;
}
}
}
}
catch (const char* err)
{
cerr << "Error:" << err << endl;
}
}
}
return 0;
}
int main(int argc, char **argv){
int ret;
pthread_t IO_thread;
ret = pthread_create(&IO_thread, NULL, IO_thread,NULL);
if(ret)
return 1;
pthread_join(IO_thread,NULL);
pthread_exit(NULL);
}
I am getting an error:
unknown type name 'Graph'
void min_vertex_cover_algorithm(Graph &graph_builder){
I am not able to find why this error is occuring. It will be very helpful if I get some solutions.
Just like you, the compiler will read from top to bottom. When it reaches the line:
void min_vertex_cover_algorithm(Graph &graph_builder){
It has to go, ok, lets use a Graph reference. It will look for the declaration of a Graph, which it cannot find, because you have declared (and defined) it below. To solve this, give the compiler a hint. Declare the Graph above the function with:
struct Graph;
void min_vertex_cover_algorithm(Graph &graph_builder){
Or simply move the whole struct definition above the function.

How to make sure that two strings only have certain alphabets in c++

Aim is to make sure that the user entered input for string 1 and string 2 contains only characters A,T,G or C in any order. If either string contains another other character then error should be displayed. Example:
Input contains error
Error in String #1: aacgttcOgMa
Error in String #2: ggataccaSat
This is my attempt at LCS.cpp file code:
#include "LCS.h"
#include <string>
using namespace std;
bool validate(string strX, string strY)
{
string x = strX;
string y = strY;
char searchItem = 'A';
char searchItem = 'C';
char searchItem = 'G';
char searchItem = 'T';
int numOfChar = 0;
int m = strX.length();
int n = strY.length();
for (int i = 0; i < m; i++)
{
if (x[i] == searchItem)
{
numOfChar++;
}
for (int i = 0; i < n; i++)
{
if (y[i] == searchItem)
{
numOfChar++;
}
}
}
This is my LCS.h file code:
#pragma once
#ifndef LCS_H
#define LCS_H
#include <string>
using namespace std;
bool validate(string strX, string strY);
#endif
And my driver file "Driver6.cpp" has this code:
#include "LCS.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string strX, strY;
cout << "String #1: ";
cin >> strX;
cout << "String #2: ";
cin >> strY;
//validate the input two strings
if (validate(strX, strY) == false)
{
return 0;
}
int m = strX.length();
int n = strY.length();
}
Didn't really want to do this but it seems like the best bet rather than going round the houses in the comments:
#include <string>
#include <iostream>
bool validate( const std::string & s ) {
for ( auto c : s ) {
if ( c != 'A' && c != 'T' && c != 'C' && c != 'G' ) {
return false;
}
}
return true;
}
int main() {
std::string s1 = "ATGCCCG";
std::string s2 = "ATGfooCCCG";
if ( validate( s1 ) ) {
std::cout << "s1 is valid\n";
}
else {
std::cout << "s1 is not valid\n";
}
if ( validate( s2 ) ) {
std::cout << "s2 is valid\n";
}
else {
std::cout << "s2 is not valid\n";
}
}
Another technique:
bool validate(const std::string& s)
{
const static std::string valid_letters("ATCGatcg");
for (auto c: s)
{
std::string::size_type position = valid_letters.find_first_of(c);
if (position == std::string::npos)
{
return false;
}
}
return true;
}
The above code searches a container of valid letters.

Check if a string is a base 16 number

I've been trying to solve this task, but I had no positive results.
So, my task is to check if a string is a base 16 number.
example : s="1AB", it will show YES 427
Here is my code.
#include <iostream>
#include <string.h>
using namespace std;
int power (int a, int b)
{
if(b==1) return a;
else return a*power(a,b-1);
}
void conv(char s[],int &n)
{
int S=0,i,p=0;
for(i=n-1;i>=0;i--)
{
if(s[i]>='0' && s[i]<='9')
S+=(s[i]-48) * power(16,p); //ex:s[i]='1' ==> S+=(49-49)*...
else S+=(s[i]-55) * power(16,p); //s[i]='A' ==> S+=(65-55) *...
p++;
}
}
int main()
{
int n,i,k=0;
char s[255];
cin.get(s,255);
cin.get();
n=strlen(s);
for(i=0;i<n;i++)
{
if(strchr("0123456789ABCDEF",s[i])) k++;
}
if(k==0) cout<<"not in base 16";
else{
conv(s,n); cout<<s;}
return 0;
}
If you want almost clean solution, you can check mine:
#include <iostream>
using namespace std;
bool IsHex(string& in) {
for (char d : in) {
if (!isxdigit(d)) return false;
}
return true;
}
int Convert(string& in) {
int val = 0;
for (char d : in) {
val = val * 16 + (isdigit(d)? d - '0' : 10 + (isupper(d)? d - 'A' : d - 'a'));
}
return val;
}
int main() {
string in;
cin >> in;
if (!IsHex(in)) cout << "Not a correct hex number" << endl;
else cout << "YES " << Convert(in) << endl;
return 0;
}
And I have made some changes in your code to make it work. You can easily find out changes.
#include <iostream>
#include <string.h>
using namespace std;
int power (int a, int b)
{
if (b == 0) return 1;
if(b==1) return a;
else return a*power(a,b-1);
}
int conv(char s[],int &n)
{
int S=0,i,p=0;
for(i=n-1;i>=0;i--)
{
if(s[i]>='0' && s[i]<='9')
S+=(s[i]-48) * power(16,p); //ex:s[i]='1' ==> S+=(49-49)*...
else S+=(s[i]-55) * power(16,p); //s[i]='A' ==> S+=(65-55) *...
p++;
}
return S;
}
int main()
{
int n,i,k=0;
char s[255];
cin.get(s,255);
cin.get();
n=strlen(s);
for(i=0;i<n;i++)
{
if(!strchr("0123456789ABCDEF",s[i])) break;
}
if(i < n) cout<<"not in base 16";
else{
cout << conv(s,n) << endl;}
return 0;
}
You can just use std::isxdigit, for example:
#include <cctype>
#include <string>
#include <iostream>
bool IsThisStringAHexNumber(std::string const &str)
{
for (size_t i = 0, n = str.length(); i < n; ++i)
if (!std::isxdigit(str[i]))
return false;
return true;
}
int main()
{
std::cout << std::boolalpha << IsThisStringAHexNumber("298722h2jjh") << std::endl;
std::cout << std::boolalpha << IsThisStringAHexNumber("2abc66f") << std::endl;
return 0;
}
Prints:
false
true

Taking Each Individual Word From a String in C++

I am writing a method in C++ which will take a string of 2 or more words and output each individual word of the string separated by a second or so, using the sleep() method. I am trying to do this using a for loop and substrings. I am unsure also of the regexs which should be used, and how they should be used, to achieve the desired output.
I have reviewed this and this and find my question differs since I am trying to do this in a loop, and not store the individual substrings.
Input:
"This is an example"
Desired output:
"This " (pause) "is " (pause) "an " (pause) "example."
Use std::stringstream, no regular expressions required:
#include <iostream>
#include <sstream>
using namespace std;
int main() {
stringstream ss("This is a test");
string s;
while (ss >> s) {
cout << s << endl;
}
return 0;
}
Also, see How do I tokenize a string in C++?
Here are a pair of implementations that don't involve creating any extraneous buffers.
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp> //for boost::copy
#include <chrono>
#include <iostream>
#include <string>
#include <experimental/string_view> //in clang or gcc; or use boost::string_ref in boost 1.53 or later; or use boost::iterator_range<char*> in earlier version of boost
#include <thread>
void method_one(std::experimental::string_view sv)
{
for(auto b = sv.begin(), e = sv.end(), space = std::find(b, e, ' ')
; b < e
; b = space + 1, space = std::find(space + 1, e, ' '))
{
std::copy(b, space, std::ostreambuf_iterator<char>(std::cout));
std::cout << " (pause) "; //note that this will spit out an extra pause the last time through
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void method_two(std::experimental::string_view sv)
{
boost::copy(
sv | boost::adaptors::filtered([](const char c) -> bool
{
if(c == ' ')
{
std::cout << " (pause) "; //note that this spits out exactly one pause per space character
std::this_thread::sleep_for(std::chrono::seconds(1));
return false;
}
return true;
})
, std::ostreambuf_iterator<char>(std::cout)
);
}
int main() {
const std::string s{"This is a string"};
method_one(s);
std::cout << std::endl;
method_two(s);
std::cout << std::endl;
return 0;
}
Live on coliru, if you're into that.
you can implement your own method:
//StrParse.h
#pragma once
#include <iostream>
static counter = 0;
char* strPar(char* pTxt, char c)
{
int lenAll = strlen(pTxt);
bool strBeg = false;
int nWords = 0;
for(int i(0); i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
i++;
}
if(strBeg)
{
nWords++;
strBeg = false;
}
}
int* pLens = new int[nWords];
int j = 0;
int len = 0;
for(i = 0; i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
i++;
len++;
}
if(strBeg)
{
pLens[j] = len;
j++;
strBeg = false;
len = 0;
}
}
char** pStr = new char*[nWords + 1];
for(i = 0; i < nWords; i++)
pStr[i] = new char[pLens[i] + 1];
int k = 0, l = 0;
for(i = 0; i < lenAll; i++)
{
while(pTxt[i] != c)
{
strBeg = true;
pStr[k][l] = pTxt[i];
l++;
i++;
}
if(strBeg)
{
pStr[k][l] = '\0';
k++;
l = 0;
strBeg = false;
}
}
counter++;
if(counter <= nWords)
return pStr[counter - 1];
else
return NULL;
}
//main.cpp
#include "StrParse.h"
void main()
{
char* pTxt = " -CPlusPlus -programming -is -a - superb thing ";
char* pStr1 = NULL;
int i = 1;
char sep;
std::cout << "Separator: ";
sep = std::cin.get();
std::cin.sync();
while(pStr1 = strPar(pTxt, sep))
{
std::cout << "String " << i << ": " << pStr1 << std::endl;
delete pStr1;
i++;
}
std::cout << std::endl;
}