I have a function that is always returning 0. The problem I believe is that data is an unsigned char, which is not part of the library. It needs to be unsigned char. So how can I make this work, because what I have doesn't.
#include <string>
#include <iostream>
int Count( const std::string & str,
const std::string & obj ) {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
std::string ::size_type pos = 0;
while( (pos = obj.find( str, pos ))
!= std::string::npos ) {
a++;
b++;
c++;
d++;
pos += str.size();
}
return a;
return b;
return c;
return d;
}
void printTcpContent(unsigned char *data,int)
{
std::string s = (const char*) data;
int a = Count( "text/html", s );
int b = Count( "text/plain", s );
int c = Count( "image/jpg", s );
int d = Count( "image/png", s );
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
std::cout << d << std::endl;
}
Try this code instead:
int Count( const std::string & strToFind,
const std::string & strToSearch ) {
int n = 0;
std::string ::size_type pos = 0;
while( (pos = strToSearch.find( strToFind, pos )) != std::string::npos ) {
n++;
pos += strToSearch.size();
}
return n;
}
Also, you can test it works by calling it with smaller test strings, eg Count("3", "1234534")
Related
I am dealing with some code that performs RC4 encryption algorithm with some params passed into the function. From there I am trying to append the generated hash to an empty string but have failed with a few of my attempts. I had seen the use of snprintf() but how could I go about converting the code below to save what gets printed to a string?
for (size_t i = 0, len = strlen(plaintext); i < len; i++) {
printf("|x%02hhx| ", hash[i]);
}
Why not use C++.
#include <iomanip>
#include <iostream>
#include <sstream>
#include <cstring>
int main() {
char plaintext[] = "12345";
char hash[] = "123\xf0\x0f";
std::stringstream out;
for (size_t i = 0, len = strlen(plaintext); i < len; i++) {
out << "|x"
<< std::setfill('0') << std::setw(2) << std::setbase(16)
// ok, maybe this is the reason.
<< 0xff & hash[i]
<< "| ";
}
std::cout << out.str();
}
Just work with std::string::data after determining the size of the output of std::snprintf:
template<class...Args>
std::string PrintFToString(char const* format, Args...args)
{
std::string result;
char c;
int requiredSize = std::snprintf(&c, 1, format, args...);
if (requiredSize < 0)
{
throw std::runtime_error("error with snprintf");
}
result.resize(requiredSize);
int writtenSize = std::snprintf(result.data(), requiredSize+1, format, args...);
assert(writtenSize == requiredSize);
return result;
}
template<class...Args>
void AppendPrintFToString(std::string& target, char const* format, Args...args)
{
char c;
int requiredSize = std::snprintf(&c, 1, format, args...);
if (requiredSize < 0)
{
throw std::runtime_error("error with snprintf");
}
auto const oldSize = target.size();
target.resize(oldSize + requiredSize);
int writtenSize = std::snprintf(target.data() + oldSize, requiredSize+1, format, args...);
assert(writtenSize == requiredSize);
}
int main() {
std::cout << PrintFToString("|x%02hhx| ", 33) << '\n';
std::string output;
for (int i = 0; i != 64; ++i)
{
AppendPrintFToString(output, "|x%02hhx| ", i);
output.push_back('\n');
}
std::cout << output;
}
Note: If you know a reasonable upper bound for the number of characters of the output, you could use a char array allocated on the stack for output instead of having to use 2 calls to std::snprintf...
I have write this code. It does not show any error but string is not reversed.please let me know where i have made the mistake?
I'm using codeblock to write code and GCC compiler. I have created two functions reverseString and printString, the printString function is working but reverseString is not working. what can i do?
#include <iostream>
#include<string>
using namespace std;
void reverseString(string s, int iNode, int lNode){
while(iNode < lNode){
char temp = s[iNode];
s[iNode] = s[lNode];
s[lNode] = temp;
iNode++;
lNode--;
}
}
void printString(string s, int n){
for(int i=0; i<n; i++){
cout << s[i];
cout << endl;
}
}
int main() {
string s;
cout << "Type String To Reverse: \n";
cin >> s;
cout << "String In Actual Order: \n";
printString(s,s.length());
reverseString(s, 0, s.length()-1);
cout << "String In Reverse Order: \n";
printString(s,s.length());
return 0;
}
This function accepts an object of the type std::string by value
void reverseString(string s, int iNode, int lNode){
while(iNode < lNode){
char temp = s[iNode];
s[iNode] = s[lNode];
s[lNode] = temp;
iNode++;
lNode--;
}
}
It means that it deals with a copy of the string used as an argument and changes the copy instead of the original string.
You have to declare the parameter as having reference type
void reverseString(string &s, int iNode, int lNode){
while(iNode < lNode){
char temp = s[iNode];
s[iNode] = s[lNode];
s[lNode] = temp;
iNode++;
lNode--;
}
}
The function could be defined simpler (without using standard features as for example std::swap) the following way
std::string & reverseString( std::string &s )
{
for ( std::string::size_type i = 0, n = s.size(); i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = c;
}
return s;
}
And the function can be called like
cout << "String In Reverse Order: \n";
std::cout << reverseString( s ) << '\n';
Without using the loop you could define the function just the following way
std::string & reverseString( std::string &s )
{
return s.assign( s.rbegin(), s.rend() );
}
As for your own function printString then it could be defined at least like
std::ostream & printString( const std::string &s, std::ostream &os = std::cout )
{
for ( char c : s )
{
os << c;
}
return os;
}
and can be called like
printString( s ) << '\n';
I wrote this program:
#include <iostream>
#include <string>
#include <ctime>
#include <sstream>
#include <time.h>
#include "TextTable.h"
using namespace std;
int command();
void new_car();
void print();
int c=0;
int c1=0;
char f;
int i=0;
int size1=0;
TextTable t( '-', '|', '*' );
struct car
{
string car_name;
string car_owner_name;
int year;
string car_paint;
string car_performance;
string car_problem;
int time;
};
car *a = NULL;
car *p;
int main ()
{
cout<<"welcome to car repair shop program. to help , press h."<<endl;
command();
}
int command(){
cout<<"admin#car_repair_shop_program # ";
cin>>f;
switch(f)
{
case 'n':
new_car();
break;
case 'h':
cout<<endl<<"help"<<endl<<"p : print"<<endl<<"n : new"<<endl<<"h : help"<<endl<<"q : quit"<<endl;
command();
break;
case 'p':
print();
break;
case 'q':
char tmp;
cout<<"Are you sure you want to quit? (y or n): ";
cin>>tmp;
switch(tmp){
case 'y':
delete [] a;
delete [] p;
return 0;
break;
case 'n':
command();
break;
default:
cout << "error! Please try again"<<endl;
command();
}
default:
cout << "error! Please try again"<<endl;
command();
}
}
void new_car()
{
c++;
string car_name;
string car_owner_name;
int year;
string car_paint;
string car_performance;
string car_problem;
int time;
p = new car[++size1];
if (c==1){
a = new car [size1-1];
}
cout<<"enter car name: ";
cin>>car_name;
cout<<endl<<"enter car owner name: ";
cin>>car_owner_name;
cout<<endl<<"enter car paint: ";
cin>>car_paint;
cout<<endl<<"enter car performance: ";
cin>>car_performance;
cout<<endl<<"enter car problem: ";
cin>>car_problem;
cout<<endl<<"enter time: ";
cin>>time;
cout<<endl<<"enter year: ";
cin>>year;
for(int i = 0 ; i < size1-1 ; ++i)
{
p[i].car_name = a[i].car_name;
p[i].car_owner_name = a[i].car_owner_name;
p[i].car_paint = a[i].car_paint;
p[i].car_performance = a[i].car_performance;
p[i].car_problem = a[i].car_problem;
p[i].time = a[i].time;
p[i].year = a[i].year;
}
delete [] a;
a = p;
a[size1-1].car_name=car_name;
a[size1-1].car_owner_name=car_owner_name;
a[size1-1].car_paint=car_paint;
a[size1-1].car_performance=car_performance;
a[size1-1].car_problem=car_problem;
a[size1-1].time=time;
a[size1-1].year=year;
cout<<"OK!"<<endl;
command();
}
void print()
{
c1++;
if (c1 == 1){
t.add( " car name " );
t.add( " car owner name " );
t.add( " car paint " );
t.add( " car performance " );
t.add( " car problem " );
t.add( " time " );
t.add( " year " );
t.endOfRow();
}
string tmp;
for (;i<size1;){
t.add(p[i].car_name);
t.add(p[i].car_owner_name);
t.add(p[i].car_paint);
t.add(p[i].car_performance);
t.add(p[i].car_problem);
tmp = to_string(p[i].time);
t.add(tmp);
tmp = to_string(p[i].year);
t.add(tmp);
t.endOfRow();
t.setAlignment( i, TextTable::Alignment::LEFT );
i+=1;
}
cout << t;
command();
}
But I can not do this part of the project:
"Check what appropriate Data Type provided by the C/C++ library can be used to store time and date information in the program above, and rewrite your program using these tools" I need to get the time and year variables.
The text of the TextTable.h file also contains the following:
#pragma once
#include <iostream>
#include <map>
#include <iomanip>
#include <vector>
#include <string>
#ifdef TEXTTABLE_ENCODE_MULTIBYTE_STRINGS
#include <clocale>
#ifndef TEXTTABLE_USE_EN_US_UTF8
#define TEXTTABLE_USE_EN_US_UTF8
#endif
#endif
class TextTable {
public:
enum class Alignment { LEFT, RIGHT };
typedef std::vector< std::string > Row;
TextTable() :
_horizontal( '-' ),
_vertical( '|' ),
_corner( '+' ),
_has_ruler(true)
{}
TextTable( char horizontal, char vertical, char corner ) :
_horizontal( horizontal ),
_vertical( vertical ),
_corner( corner ),
_has_ruler(true)
{}
explicit TextTable( char vertical ) :
_horizontal( '\0' ),
_vertical( vertical ),
_corner( '\0' ),
_has_ruler( false )
{}
void setAlignment( unsigned i, Alignment alignment )
{
_alignment[ i ] = alignment;
}
Alignment alignment( unsigned i ) const
{ return _alignment[ i ]; }
char vertical() const
{ return _vertical; }
char horizontal() const
{ return _horizontal; }
void add( std::string const & content )
{
_current.push_back( content );
}
void endOfRow()
{
_rows.push_back( _current );
_current.assign( 0, "" );
}
template <typename Iterator>
void addRow( Iterator begin, Iterator end )
{
for( auto i = begin; i != end; ++i ) {
add( * i );
}
endOfRow();
}
template <typename Container>
void addRow( Container const & container )
{
addRow( container.begin(), container.end() );
}
std::vector< Row > const & rows() const
{
return _rows;
}
void setup() const
{
determineWidths();
setupAlignment();
}
std::string ruler() const
{
std::string result;
result += _corner;
for( auto width = _width.begin(); width != _width.end(); ++ width ) {
result += repeat( * width, _horizontal );
result += _corner;
}
return result;
}
int width( unsigned i ) const
{ return _width[ i ]; }
bool has_ruler() const { return _has_ruler;}
int correctDistance(std::string string_to_correct) const
{
return static_cast<int>(string_to_correct.size()) - static_cast<int>(glyphLength(string_to_correct));
};
private:
const char _horizontal;
const char _vertical;
const char _corner;
const bool _has_ruler;
Row _current;
std::vector< Row > _rows;
std::vector< unsigned > mutable _width;
std::vector< unsigned > mutable _utf8width;
std::map< unsigned, Alignment > mutable _alignment;
static std::string repeat( unsigned times, char c )
{
std::string result;
for( ; times > 0; -- times )
result += c;
return result;
}
unsigned columns() const
{
return _rows[ 0 ].size();
}
unsigned glyphLength( std::string s ) const
{
unsigned int _byteLength = s.length();
#ifdef TEXTTABLE_ENCODE_MULTIBYTE_STRINGS
#ifdef TEXTTABLE_USE_EN_US_UTF8
std::setlocale(LC_ALL, "en_US.utf8");
#else
#error You need to specify the encoding if the TextTable library uses multybyte string encoding!
#endif
unsigned int u = 0;
const char *c_str = s.c_str();
unsigned _glyphLength = 0;
while(u < _byteLength)
{
u += std::mblen(&c_str[u], _byteLength - u);
_glyphLength += 1;
}
return _glyphLength;
#else
return _byteLength;
#endif
}
void determineWidths() const
{
_width.assign( columns(), 0 );
_utf8width.assign( columns(), 0 );
for ( auto rowIterator = _rows.begin(); rowIterator != _rows.end(); ++ rowIterator ) {
Row const & row = * rowIterator;
for ( unsigned i = 0; i < row.size(); ++i ) {
_width[ i ] = _width[ i ] > glyphLength(row[ i ]) ? _width[ i ] : glyphLength(row[ i ]);
}
}
}
void setupAlignment() const
{
for ( unsigned i = 0; i < columns(); ++i ) {
if ( _alignment.find( i ) == _alignment.end() ) {
_alignment[ i ] = Alignment::LEFT;
}
}
}
};
inline std::ostream & operator<<( std::ostream & stream, TextTable const & table )
{
table.setup();
if (table.has_ruler()) {
stream << table.ruler() << "\n";
}
for ( auto rowIterator = table.rows().begin(); rowIterator != table.rows().end(); ++ rowIterator ) {
TextTable::Row const & row = * rowIterator;
stream << table.vertical();
for ( unsigned i = 0; i < row.size(); ++i ) {
auto alignment = table.alignment( i ) == TextTable::Alignment::LEFT ? std::left : std::right;
// std::setw( width ) works as follows: a string which goes in the stream with byte length (!) l is filled with n spaces so that l+n=width.
// For a utf8 encoded string the glyph length g might be smaller than l. We need n spaces so that g+n=width which is equivalent to g+n+l-l=width ==> l+n = width+l-g
// l-g (that means glyph length minus byte length) has to be added to the width argument.
// l-g is computed by correctDistance.
stream << std::setw( table.width( i ) + table.correctDistance(row[ i ])) << alignment << row[ i ];
stream << table.vertical();
}
stream << "\n";
if (table.has_ruler()) {
stream << table.ruler() << "\n";
}
}
return stream;
}
What appropriate Data Type provided by the C/C++ library can be used?
You might want to look up std::time on a site like http://www.cppreference.com. There is a lot of information there.
sorry for the noob question.
I have the following code for an assignment in my class (includes the assignment description):
Write a program which asks the user to enter a string and then passes it to a void recursive function which displays the string in reverse. The prototype of the function would be:
void reverse(string s, int i);
The function call would be:
reverse(strIn, strIn.length());
A typical run will be:
Enter a string:
Four score and seven years ago ..
.. oga sraey neves dna erocs ruoF
// Actual code
#include <iostream>
#include <string>
void reverse(std::string, int);
int main() {
std::string input;
std::cout << "Enter a string." << std::endl;
getline(std::cin, input);
int i = input.length() - 1;
reverse(input, i);
return 0;
}
void reverse(std::string input, int i) {
while (i >= 0) {
std::cout << input.at(i);
i--;
reverse(input, i);
}
}
I assumed that by subtracting 1 each time would display the last character in the string, and setting the loop condition to i >= 0 would make the loop terminate when there's no more characters left in the string. But I'm getting the following output:
sleepy#mooncell ~/CMPSC121/Activities $ ./a.out
Enter a string.
help
plehhehhlehhehh
I can't figure out what I'm doing wrong here. Help is much appreciated!
This is because you are trying to perform recursion and a while loop at the same time, just get rid of the while loop and it will work, the code should look something like this:
// Actual code
#include <iostream>
#include <string>
void reverse(std::string, int);
int main() {
std::string input;
std::cout << "Enter a string." << std::endl;
getline(std::cin, input);
int i = input.length() - 1;
reverse(input, i);
return 0;
}
void reverse(std::string input, int i) {
if(i <0)
return;
std::cout << input.at(i);
i--;
reverse(input, i);
}
This function
void reverse(std::string input, int i) {
while (i >= 0) {
std::cout << input.at(i);
i--;
reverse(input, i);
}
}
is not pure recursive because it uses a while loop.
Also it is a bad idea to pass the string by value. And the position in the string should have the type std::string::size_type.
The second parameter can have a default argument. in this case a function call will look much simpler
reverse( input );
Pay attention to that these statements can invoke undefined behavior when an empty string is passed to the function
int i = input.length() - 1;
reverse(input, i);
Because in this case the variable i will have maximum value. That is this declaration
int i = input.length() - 1;
in fact will be equivalent to
int i = std::string::size_type( -1 );
What you need is the following
void reverse( const std::string &s, std::string::size_type i = 0 )
{
if ( i < s.size() )
{
char c = s[i];
reverse( s, i + 1 );
std::cout << c;
}
}
Here is a demonstrative program.
#include <iostream>
#include <string>
void reverse( const std::string &s, std::string::size_type i = 0 )
{
if ( i < s.size() )
{
char c = s[i];
reverse( s, i + 1 );
std::cout << c;
}
}
int main()
{
const char *s = "Hello bbchan";
std::cout << s << '\n';
reverse( s );
std::cout << '\n';
return 0;
}
Its output is
Hello bbchan
nahcbb olleH
And even better to define the function the following way as it is shown in the demonstrative program below. In this case you can for example write a string in the reverse order in a file.
#include <iostream>
#include <string>
std::ostream & reverse( const std::string &s,
std::string::size_type i = 0,
std::ostream &os = std::cout )
{
if ( i < s.size() )
{
char c = s[i];
reverse( s, i + 1, os );
os << c;
}
return os;
}
int main()
{
const char *s = "Hello bbchan";
std::cout << s << '\n';
reverse( s ) << '\n';
return 0;
}
so let's say I have a main function with some arbitrary code:
void main(){
//Some random code
int a = 5;
int b = a + 7;
}
and the text of this function is stored inside an std::string:
std::string mystring("void main(){ //Some random code int a = 5; int b = a + 7;}");
I want to use std::regex in order to extract out the body of the function. So the result I would be getting back is:
"//Some random code int a= 5; int b = a + 7;"
My issue is I do not know how to format the regular expression to get what I want. Here is my code I have right now:
std::string text("void main(){ //Some random code int a = 5; int b = a + 7;}");
std::regex expr ("void main()\\{(.*?)\\}");
std::smatch matches;
if (std::regex_match(text, matches, expr)) {
for (int i = 1; i < matches.size(); i++) {
std::string match (matches[i].first, matches[i].second);
std::cout << "matches[" << i << "] = " << match << std::endl;
}
}
My regex is completely off and returns no matches. What do I need to make my regex in order for this to work?
As discussed in the comments OP only wants to "extract the text inside the function body, regardless of what that text is".
#OP:
Your regex is wrong as you don't escape the parenthesis for main().
Changing the regex to "void main\\(\\)\\{(.*?)\\}" will work.
I also recommend to use size_t for i in your for-loop so you don't compare signed with unsigned (std::smatch::size() returns size_t).
#include <iostream>
#include <regex>
int main()
{
std::string text("void main(){ //Some random code int a = 5; int b = a + 7;}");
std::regex expr("void main\\(\\)\\{(.*?)\\}");
std::smatch matches;
if (std::regex_match(text, matches, expr)) {
for (size_t i = 1; i < matches.size(); i++) {
std::string match(matches[i].first, matches[i].second);
std::cout << "matches[" << i << "] = " << match << std::endl;
}
}
}
Output:
matches[1] = //Some random code int a = 5; int b = a + 7;
This solution fails for the input "void main(){ while(true){ //Some random code int a = 5; int b = a + 7; } }"
The easiest solution to this would be to change the regex to "^void main\\(\\)\\{(.*?)\\}$" but that requires the input to start with "void main(){" and end with "}"
As proposed by Revolver_Ocelot you can also add some whitespace matching into the regex to make it a little bit more flexible.
As suggested in your use case it would probably be the best to just rely on string search and matching of braces.
#include <iostream>
#include <regex>
std::string getBody(const std::string& functionDef, const std::string& text)
{
size_t pos = 0;
do
{
if ((pos = text.find(functionDef, pos)) == std::string::npos)
continue;
pos += functionDef.length();
size_t firstSemicolon = text.find(";", pos);
size_t firstOpen = text.find("{", pos);
size_t firstClose = text.find("}", pos);
if (firstSemicolon != std::string::npos && firstSemicolon < firstOpen) //Only function declaration
continue;
if (firstOpen == std::string::npos || firstClose == std::string::npos || firstClose < firstOpen) //Mismatch
continue;
size_t bodyStart = pos = firstOpen + 1;
size_t bracesCount = 1;
do
{
firstOpen = text.find("{", pos);
firstClose = text.find("}", pos);
if (firstOpen == std::string::npos && firstClose == std::string::npos)//Mismatch
{
pos = std::string::npos;
continue;
}
//npos is always larger
if (firstOpen < firstClose)
{
bracesCount++;
pos = firstOpen + 1;
}
else if (firstOpen > firstClose)
{
bracesCount--;
if (bracesCount == 0)
{
size_t bodySize = firstClose - bodyStart;
return text.substr(bodyStart, bodySize);
}
pos = firstClose + 1;
}
else
{
//Something went terribly wrong...
pos = std::string::npos;
continue;
}
} while (pos != std::string::npos);
}
while (pos != std::string::npos);
return std::string();
}
int main()
{
std::string text("void main(); int test(); void main(){ while(true){ //Some {random} code int a = 5; int b = a + 7; } } int test(){ return hello; } ");
std::cout << getBody("void main()", text) << std::endl;
std::cout << getBody("int test()", text) << std::endl;
}
Output:
while(true){ //Some {random} code int a = 5; int b = a + 7; }
return hello;
The code can also handle newlines and skips function declarations. I tried to write it as clear as possible.
If there are still questions feel free to ask.