comparing what two pointers point to - c++

I'm writing a program to detect phishing. I'm trying to check if the base of the URL, if it is same in the tag or not.
For e.g. in http://maps.google.com"> www.maps.yahoo.com
I'm trying to check if the last 2 parts of the URL are same or not, i.e. if google.com = yahoo.com or not.
I'm using the following code to do so:
void checkBase(char *add1, char *add2){
char *base1[100], *base2[100];
int count1 = 0, count2 = 0;
base1[count1] = strtok(add1, ".");
while(base1[count1] != NULL){
count1++;
base1[count1] = strtok(NULL, ".");
}
base2[count2] = strtok(add2, ".");
while(base2[count2] != NULL){
count2++;
base2[count2] = strtok(NULL, ".");
}
if((base1[count1-1] != base2[count2-1]) && (base1[count1-2] != base2[count2-2])){
cout << "Bases do not match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
}
else{
cout << "Bases match: " << endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << endl;
}
}
I'm not sure if i'm comparison in the if statement is right or not. I'm passing in two URL's.
Thanks

this is comparing the two pointers char* (as you point out;) )
base1[count1-1] != base2[count2-1])
use this instead
strcmp(base1[count1-1], base2[count2-1]) != 0
you could use std:string and boost tokenizer (now C++11 I think)
regards

You can't compare strings by comparing their addresses, two identical strings can be stored in different addresses. To compare them you should you strcmp:
if(strcmp(base1[count1-1], base2[count2-1]) != 0 ||
strcmp(base1[count1-2], base2[count2-2])!=0){
std::cout << "Bases do not match: " << std::endl
<< base1[count1-2] << "." << base1[count1-1] << " and "
<< base2[count2-2] << "." << base2[count2-1] << std::endl;
}
You can do similar with C++ tools:
void checkBase(std::string a1, std::string a2){
size_t a1_start = a1.rfind('.'), a2_start = a2.rfind('.');
a1_start = a1.rfind('.', a1_start-1);
a2_start = a2.rfind('.', a2_start-1);
std::string h1 = a1.substr(a1_start+1), h2 = a2.substr(a2_start+1);
if (h1 == h2)
std::cout << "same" << std::endl;
else
std::cout << "not same" << std::endl;
}

Related

How can I remove values from output statement given a condition? - c++

I'm a little confused as to how to go around this. I have some array variables with some information, and I want to print them out after some calculations. If the value is 0, then I want to print a " " instead. There are 3 arrays that need to get checked however, how would I change the output statement to cater for all 3 checks and print an empty string instead of the value?
for(int start = 1; start < 13; start++)
{
if(check[start] == 1)
{
cout << checkMonth(start) << ": " << setprecision(1) << fixed << averagespeed[start] << "(" << setprecision(1) << fixed << sdSpeed[start] << ")," << setprecision(1) << fixed << averagetemp[start] << "(" << setprecision(1) << fixed << sdTemp[start] << ")," << setprecision(1) << fixed << Solar[start] << '\n';
}
/*if(sumTemp[start] == 0 || sumTemp[start] == 0 || sumSpeed[start] == 0){
}*/
}
Example Output looks like this:
January,5.5(1.2),25.5(12.2),196.4
For example if Sum of Speed is 0, that means all values of speed were 0 or null. So it should change to this:
January,,25.5(12.2),196.4
A single line to std::cout doesn't need to be done in one statement. For example:
std::cout << "First";
std::cout << ", second"
std::cout << ", third\n"
Prints the following line:
First, second, third
Now we can use an if to conditionally print the middle part of the string:
std::cout << a;
if (b != 0) {
std::cout << ", " << b;
}
std::cout << ", " << c << '\n';

simple game, while loop and checking strings

I am a beginner at c++ and I want to create simple game. You have vector of strings, then you check if line input matched the right answer.
I want to generate random number 1 ,2 or 3. Then check if line matches correct answer and count the points.
I am probably missing something basic, yet I dont know what.
Problems:
Input line get correctly read on only first iterations
somehow points (tocke) jumps to 45763 after finishing.
At beginning time (cas) is sometimes 2.
Code:
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <string>
int main() {
int runde;
int tocke;
int cas;
std::cout << "\n" << "Pravila igre:" << "\n" << "Za pravilen odgovor dobis 1 tocko, za napacnega zgubis 2!"<<
"\n" << "Stevilo zivljenj si izberes sama!"<< "\n" << "\n" ;
std::cout << "Izberi stevilo zivljenj!:" << "\n";
std::cin >> runde ;
std::vector<std::string> latin = {"carum carvi", "artemisia absiinthium","coriandrum sativum"};
std::vector<std::string> slovene = {"navadna kumina", "pravi pelin", "koriander"};
tocke << 0;
cas << 0;
do {
int ind;
cas << cas + 1;
std::cout << "Round " << cas <<"! Ladies and gentlemans, buckle your seatbelts!"<<"\n" << "\n" ;
ind = std::rand() % 3;
std::cout << "ime rastline: " << slovene[ind] << "\n";
std::cin.ignore();
std::string line;
getline(std::cin, line);
std::cout << "\n";
if (latin[ind] == line){
std::cout << "Pravlino! Tocka zate!" << "\n";
tocke << tocke + 1;
std::cout << "Tocke == " << tocke << "\n" << "Zivjenja == " << runde << "\n" << "Prezivete runde == " << cas << "\n"<< "\n";
}
else
{
std::cout << "Napaka! :D" << "\n";
std::cout << "Pravilen odgovor == " << latin[ind] << "\n";
-- runde ;
tocke << tocke - 2;
std::cout << "Tocke == " << tocke << "\n" << "Zivjenja == " << runde << "\n" << "Prezivete runde == " << cas << "\n"<< "\n";
}
}while(runde >= 0 );
std::cout << "\n"<<"Stevilo tock == " << tocke <<"\n" << "St. prezivetih rund == " << cas - 1
<< "\n" ;
}
You seem to have a misconception regarding operators. << is NOT assignment, use = instead. So tocke << 0; doesn't assign 0 to tocke, it does bitshifting (on an uninitialized variable), then discards the result. tocke stays uninitialized and this causes problems later.
Instead of this:
tocke << 0;
cas << 0;
Do this:
tocke = 0;
cas = 0;
Also instead of cas << cas + 1; do cas++ and instead of tocke << tocke - 2; do tocke -= 2;. To learn how the assignment operators work, you can read about them here. Last but not least, try to see if your compiler gives you any warnings, it should complain about using uninitialized values.

I need to have spaces between outputted _

I have just more or less finished my first C++ Project, it is a Hangman Game and so far everything works fine. The only Problem is that i need to have spaces between the underlines (_) that represent the hidden word. If anyone could help me on this i would really appreciate it.
// UNCOMMENT THE FOLLOWING LINE (REMOVE THE TWO SLASHES AT THE BEGINNING) TO RUN AUTOMATIC TESTS
#include "tests.h"
#include <iostream>
#include <string>
#include "hangman.h"
int main(){
using namespace std;
// display the hidden word
std::string word_to_guess = chooseWord();
int misses = 0;
std::string displayed_word = word_to_guess;
for(int i=0; i< displayed_word.length(); i++)
displayed_word[i] = '_';
int attempts = 6;
std::cout << "Attempts left:" << attempts << std::endl;
std::cout << "[ " << displayed_word << " ]" << std::endl;
//check for correct letter
while(1){
std::cout << "Your guess";
std::cout << ":";
char guess;
std::cin >> guess;
bool Correct = false;
for(int i=0; i< word_to_guess.length(); i++)
if (guess == word_to_guess[i]) {
displayed_word[i] = word_to_guess[i];
Correct = true;
}
if (!Correct)
attempts--;
if (!Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (!Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
if (Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
//check for win or lose
if (attempts==0)
std::cout << "The word was: " << word_to_guess << std::endl << "You lost!";
if (attempts==0)
return 0;
if (!word_to_guess.find(displayed_word))
std::cout << "You won!";
if (!word_to_guess.find(displayed_word))
return 0;
}
}
First, you can simplify this
if (!Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (!Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
if (Correct)
std::cout << "Attempts left:" << attempts << std::endl;
if (Correct)
std::cout << "[ " << displayed_word << " ]" << std::endl;
by this
std::cout << "Attempts left:" << attempts << std::endl;
std::cout << "[ " << displayed_word << " ]" << std::endl;
Now, about your question, I think a best solution is replacing
std::cout << "[ " << displayed_word << " ]" << std::endl;
by this
std::cout << "[";
for(int i = 0; i < displayed_word.length(); i++) {
if(i == 0 || displayed_word[i] == '_')
std::cout << " ";
std::cout << displayed_word[i];
if(i == displayed_word.length()-1 || (displayed_word[i] == '_' && displayed_word[i+1] != '_'))
std::cout << " ";
}
std::cout << "]" << std::endl;
Explaination:
We put spaces at the beginning and the end, and also around underscores, but we make sure to put only one space between two underscores.

Why does a nullptr terminated array passed to function through ***char loose the termination element? [duplicate]

This question already has answers here:
Passing a char pointer array to a function
(2 answers)
Closed 8 years ago.
Note 1: I am not looking for different solutions to the problem at hand. I'm curious about what actually is happening here.
Note 2: I'm doing this in c++ context, but am assuming that this also applies to C, hence the C tag. (apart from the representation of a null pointer)
This is about c-strings and access to original from a function. I'll use argv and argc to illustrate that the array should be nullptr terminated. I declare them like this:
int argc = 1;
char **argv = (char**) malloc( (argc + 1) * sizeof(char*) );
argv[0] = (char*)"argument 0";
argv[1] = nullptr;
If I declare a function like this: func1(int &f_argc, char **f_argv) I can access all elements inside the function scope, including f_argv[f_argc], which is nullptr, but I cannot modify the original argv to point to a different address as f_argv in the function is a value passed copy of the original pointer. It has a different address in memory.
If I declare the function like this instead: func2(int &f_argc, char ***f_argv), I can access the original argv through *f_argv in the function, but the last element (which should be nullptr) is cut off. This means that if I try to check for the terminating nullptr inside the function, I try to access an element outside the range of the array, resulting in a core dump at runtime.
Q1: Why is f_argv cut off when reaching the nullptr in func2, but not in func1?
Q2: Is there a way to get write access to the original argv from within the function, without removing the terminator?
Edit: (added code to show what I mean)
#include <iostream>
#include <cstring>
void func1(int &f_argc, char **f_argv) {
using std::cout;
using std::endl;
cout << " In function:" << endl;
cout << " argv passed as **f_argv" << endl;
cout << " f_argv = " << f_argv << " , &f_argv = " << &f_argv << endl;
for (int pos = 0; pos < f_argc; pos++) {
if (f_argv[pos] != nullptr) {
cout << " f_argv[" << pos << "] = \"" << f_argv[pos] << "\"" << endl;
} else {
cout << " f_argv is prematurely terminated" << endl;
}
}
if (f_argv[f_argc] == nullptr) {
cout << " f_argv is correctly terminated" << endl;
} else {
cout << " f_argv[" << f_argc << "] = \"" << f_argv[f_argc] << "\"" << endl;
cout << " f_argv is not terminated" << endl;
}
// Intention is to copy argv here, add elements, terminate it with
// nullptr and change original argv to point to copy. This wouldn't
// work in this function, as &f_argv != &argv.
return;
}
void func2(int &f_argc, char ***f_argv) {
using std::cout;
using std::endl;
cout << " In function:" << endl;
cout << " array passed as ***f_argv" << endl;
cout << " f_argc = " << f_argc
<< " , &f_argc = " << &f_argc << endl;
cout << " *f_argv = " << *f_argv
<< " , f_argv = " << f_argv << endl;
for (int pos = 0; pos < f_argc; pos++) {
cout << " about to check: "
<< "if (*f_argv[" << pos << "] != nullptr)" << endl;
if (*f_argv[pos] != nullptr) {
cout << " *f_argv[" << pos << "] = \""
<< *f_argv[pos] << "\"" << endl;
} else {
cout << " *f_argv is prematurely terminated" << endl;
}
}
if (*f_argv[f_argc] == nullptr) {
cout << " *f_argv is correctly terminated" << endl;
} else {
cout << " *f_argv[" << f_argc << "] = \""
<< *f_argv[f_argc] << "\"" << endl;
cout << " *f_argv is not terminated" << endl;
}
// Intention is to copy argv here, add elements, terminate it with
// nullptr and change original argv to point to copy.
return;
}
// --------------------------------------------
int main() {
using std::cout;
using std::endl;
int argc=1;
char **argv = (char**) malloc( (argc + 1) * sizeof(char*) );
argv[0] = (char*)"argument 0";
argv[1] = nullptr;
cout << "Before function call" << endl;
cout << "argv = " << argv << " , &argv = " << &argv << endl;
for (int i = 0; i < argc; i++) {
if (argv[i] != nullptr) {
cout << "argv[" << i << "] = \"" << argv[i] << "\"" << endl;
} else {
cout << "argv is prematurely terminated" << endl;
}
}
if (argv[argc] == nullptr) {
cout << "argv is correctly terminated" << endl;
} else {
cout << "argv[" << argc << "] = \"" << argv[argc] << "\"" << endl;
cout << "argv is not terminated" << endl;
}
// run one of these
//func1(argc, argv);
func2(argc, &argv);
free(argv);
return 0;
}
If running func2, running the program results in a core dump at this line:
if (*f_argv[f_argc] == nullptr) {
The subscript operator has higher precedence than the dereference operator. *f_argv[f_argc] is *(f_argv[f_argc]). What you want is (*f_argv)[f_argc].
Since you are using C++, you should consider taking f_argv by reference - void f(int &f_argc, char **& f_argv);.

Char array outputting extra characters

Hello this is a segment of my code of which i am trying to implement the Morris-Pratt algorithm.
When i am comparing my variables if find that they dont match, this is because one of my variables "Temp" is geting extra characters added to the end of the array.
here is my code...
// Calculate the next talbe
char test[searchLen];
for(int i = 0; i < searchLen; i++)
{
test[i] = fileContent[currPos+i];
}
cout << "SEARCHLEN: " << searchLen << endl;
cout << "TEST: " << '\t' << '\t' << test << endl;
cout << "SEARCH: " << '\t' << search << endl;
cout << strcmp(test,search) << endl << endl;
// Determine if a match is detected
if(strcmp(test,search)==0)
{
cout << "----------------------> Match detected at: " << currPos << endl;
}
currPos ++;
}
return numberOfComparisons;
}
The output looks like this...
SEARCHLEN: 8
TEST: athsoutg5?h
SEARCH: brilling
-1
As you can see the 5?H is not supposed to be there and is breaking my code.
You need to add a null terminator.
char test[searchLen + 1];
test[searchLen] = '\0';
It does look like your string is not terminated with \0, maybe you forgot to copy it / put it in there?