calculate length of unsigned char - c++

here i have code for calculate hash value of unsigned char
#include <cstdlib>
#include <iostream>
#include<string.h>
using namespace std;
unsigned oat_hash(unsigned char *key,int len)
{
unsigned char *p=key;
unsigned h=0;
int i;
for(i=0;i<len;++i){
h+=p[i];
h+=(h<<10);
h^=(h>>6);
}
h+=(h<<3);
h^=(h>>11);
h+=(h<<15);
return h;
}
using namespace std;
int main(int argc, char *argv[])
{
unsigned char mystring[]="123456789abcdef";
unsigned char *key=&mystring[0];
int n=sizeof(mystring)/sizeof(mystring[0]);//length of mystring
cout<<oat_hash(key,n)<<endl;
//system("PAUSE");
//return EXIT_SUCCESS;
return 0;
}
name of this hash function is so called One-at-a-Time hash(by Bob Jenkins) i have one question is this little part of code correct?
int n=sizeof(mystring)/sizeof(mystring[0]);//length of mystring
because mysting has not built-in function length,i used this

Under the circumstances, yes -- but it's pretty fragile. For example, if you changed your definition from:
unsigned char mystring[]="123456789abcdef";
To:
unsigned char *mystring="123456789abcdef";
Your method of finding the length would produce completely incorrect results. Also note that since your string is made up of chars, the /sizeof(mystring[0]) isn't really necessary either -- sizof(char) == 1 (and the same for signed char or unsigned char).
You normally want to use strlen instead.

Yeah, your code is correct. You may want to compare against the data-type though:
int n=sizeof(mystring) / sizeof(char); //length of mystring
Note that this only works if the string isn't dynamic.
Otherwise use strlen for c-style strings.
I must say, however, C++'s std::string does have a length method, and is much easier to use in the majority of cases - especially when using them with the STL.
Also, boost can do C++ string hashes

Yes I feel that the code will work fine. But ensure that if you pass an array of a string through a method it would not give you the desired result since passing array in functions implicitly passed by a pointer. That time your code can provide a disaster. Other wise it is fine. The other way you can find the length of a string array is like:
int len = 0;
int iCount = 0;
while (mystring[iCount].empty() != true)
{
iCount++;
len++;
}
Then use len as length of the String array
Hope this will help.

Related

Pointer to char vs String

Consider these two pieces of code. They're converting base10 number to baseN number, where N is the number of characters in given alphabet. Actually, they generate permutations of letters of given alphabet. It's assumed that 1 is equal to first letter of the alphabet.
#include <iostream>
#include <string>
typedef unsigned long long ull;
using namespace std;
void conv(ull num, const string alpha, string *word){
int base=alpha.size();
*word="";
while (num) {
*word+=alpha[(num-1)%base];
num=(num-1)/base;
}
}
int main(){
ull nu;
const string alpha="abcdef";
string word;
for (nu=1;nu<=10;++nu) {
conv(nu,alpha,&word);
cout << word << endl;
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned long long ull;
void conv(ull num, const char* alpha, char *word){
int base=strlen(alpha);
while (num) {
(*word++)=alpha[(num-1)%base];
num=(num-1)/base;
}
}
int main() {
char *a=calloc(10,sizeof(char));
const char *alpha="abcdef";
ull h;
for (h=1;h<=10;++h) {
conv(h,alpha,a);
printf("%s\n", a);
}
}
Output is the same:
a
b
c
d
aa
ba
ca
da
No, I didn't forget to reverse the strings, reversal was removed for code clarification.
For some reason speed is very important for me. I've tested the speed of executables compiled from the examples above and noticed that the one written n C++ using string is more than 10 times less fast than the one written in C using char *.
Each executable was compiled with -O2 flag of GCC. I was running tests using much bigger numbers to convert, such as 1e8 and more.
The question is: why is string less fast than char * in that case?
Your code snippets are not equivalent. *a='n' does not append to the char array. It changes the first char in the array to 'n'.
In C++, std::strings should be preferred to char arrays, because they're a lot easier to use, for example appending is done simply with the += operator.
Also they automatically manage their memory for you which char arrays don't do. That being said, std::strings are much less error prone than the manually managed char arrays.
Doing a trace of your code you get:
*a='n';
// 'n0000'
// ^
// a
++a;
// 'n0000'
// ^
// a
*a='o'
// 'no000'
// ^
// a
In the end, a points to its original address + 1, wich is o. If you print a you will get 'o'.
Anyways, what if you need 'nothing' instead of 'no'? It wont fit in 5 chars and you will need to reallocate mem etc. That kind of things is what string class do for you behind the scenes, and faster enough so it's not a problem almost every scenario.
It's possible to use both char * and string to handle some text in C++. It seems to me that string addition is much slower than pointer addition. Why does this happen?
That is because when you use a char array or deal with a pointer to it (char*) the memory is only allocated once. What you describe with "addition" is only an iteration of the pointer to the array. So its just moving of a pointer.
// Both allocate memory one time:
char test[4];
char* ptrTest = new char[4];
// This will just set the values which already exist in the array and will
// not append anything.
*(ptrTest++) = 't'
*(ptrTest++) = 'e';
*(ptrTest++) = 's';
*(ptrTest) = 't';
When you use a string instead, the += operator actually appends characters to the end of your string. In order to accomplish this, memory will be dynamically allocated every time you append something to the string. This process does take longer than just iterating a pointer.
// This will allocate space for one character on every call of the += operator
std::string test;
test += 't';
test += 'e';
test += 's';
test += 't';
std::string a(2,' ');
a[0] = 'n';
a[1] = 'o';
Change the size of your string in the constructor or use the reserve, resize methods, that is your choice.
You are mixing different things in your question, one is a raw representation of bytes that can get interpreted as a string, no semantics or checks, the other is an abstraction of a string with checks, believe me, it is a lot of more important the security and avoid segfaults that can lead on code injection and privilege escalation than 2ms.
From the std::string documentation (here) you can see, that the
basic_string& operator+=(charT c)
is equivalent to calling push_back(c) on that string, so
string a;
a+='n';
a+='o';
is equivalent to:
string a;
a.push_back('n');
a.push_back('o');
The push_back does take care of a lot more than the raw pointer operations and is thus slower. It for instance takes care of automatic memory management of the string class.

assigning const char *ptr to an array parameter? C++

FYI: the answer provided was wrong, I have found an answer, they are written below.
In an exam question, was given a function prototype
void store(double *ptr, unsigned int length, char filename[]);
we are asked to call this function in order to do stuff... (not relevant to my question now).
but we need to pass a filename for reading. and it must be received by this filename[] char array.
below is the answer that is provided. (it's a previous years' exam).
#include <iostream>
using namespace std;
#define SIZE 10
int main(void)
{
const char *filename = "array.dat";
double a[SIZE];
for ( unsigned n = 0; n < SIZE; n++ )
a[n] = 0.0;
store(a, SIZE, filename); // if simply send "array.dat" as parameter it works.
return 0;
}
however, this does not compile to me. in my mind it doesn't compile either, because I can't assign a c-style string like this to a char array, in this way, or so i believed. I've searched a fair bit, i just need some clarity on this. thanks.
The line
const char *filename = "array.dat";
defines filename to be of type const char*. It cannot be used as an argument to store since store expects char [] type.
Change the declaration of filename to:
char filename[] = "array.dat";
If the store function doesn't need to change the filename content then it should be a const. The function prototype is not well and you have to do some workaround. Copy the string to a non-const array and pass it instead, or just use a non-const string.
char filename[] = "array.dat";

How to call a function of this type

/* Write a function that returns the length of a string(char *), excluding the final NULL
character.It should not use any standard - library functions.You may use arithmetic and
dereference operators, but not the indexing operator ([]) */
#include "stdafx.h"
#include<iostream>
using namespace std;
int stringLength(const char * str) {
int length = 0;
while (*(str + length) != '\0') {
++length;
cout << length;
return length;
}
int _tmain(int argc, _TCHAR* argv[]){
stringLength({ 'a', 'b', 'c', '\0' });
return 0;
}
Somehow I think I am not calling my function properly in the main function, but I am not sure how else I should do it. What is the proper way of calling a function of this type? (Sorry if this is a stupid question: I am new to C++)
Like: int l = stringLength("abc");
C constant strings are automatically zero terminated, so you don't need to specify the extra zero character.
Pass a string. For instance
int len = stringLength("abc");
FWIW, it would be idiomatic to use size_t for the return type of this function. When you try to work with other code you'll meet resistance to having used int rather than size_t.
The code in the question is also rather poorly formatted and does not compile. You omitted a closing brace. It pays to get this sort of detail just right.

Different behavior with different types of arrays

i have tested two different varianat of similary code ,suppose i have char array
char x[]="snow comes in winter ";
then following code
#include <iostream>
#include <string.h>
using namespace std;
int main(){
char x[]="snow comes in winter ";
int k=0;
int n=3;
cout<<x+n-k+1<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
prints "comes in winter "
while following
#include <iostream>
#include <string.h>
using namespace std;
int main(){
//char x[]="snow comes in winter ";
int a[]={12,3,2,4,5,6,7};
int k=0;
int n=3;
cout<<a+n-k+1<<endl;
return 0;
}
prints 0xbffd293c
if we change it a bit
#include <iostream>
#include <string.h>
using namespace std;
int main(){
//char x[]="snow comes in winter ";
int a[]={12,3,2,4,5,6,7};
int k=0;
int n=3;
cout<<*(a+n-k+1)<<endl;
return 0;
}
prints number 5.
so my question is why we can access in case of char array so easily?what is main reason of it?i am very curiousy and please could anybody explain me?
why we can access in case of char array so easily?
Because there's a convention that C strings are represented by char*, people assume char* are actually strings. The iostreams follow that and overload output for char* to print the string, whereas for an int* (in your second example), they print the representation of the address.
BTW there is a similar overload for input, which is most unfortunate, since you can't control that to prevent buffer overflows. ie. don't do this:
char x[10];
std::cin >> x;
The reasons for this go back to C.
In C, char* is typically used to represent a NUL-terminated string (as opposed to a pointer to an individual char). Therefore, functions taking char* typically treat the argument as a string. In this case the function is operator<<, and what it does is print the argument out as a string.
No such thing can be said about int*, which is just that, a pointer to an int. Here, operator<< prints out the value of the pointer (i.e. the address). It's only when you explicitly dereference the pointer that the pointed-to value gets printed.
The left shift operator for cout is overloaded to handle char pointers. Meaning, when you give it a pointer to a char, it dereferences the pointer for you and so you get the data pointed to. This does not happen in the case of an int because there is no overload, and so you must dereference the pointer yourself.
Given a variable foo of type Foo*, the expression foo+n is also of type Foo* (assuming n is an integral type).
The default std::ostream mechanism for printing a pointer is to print the pointer. There is an override specifically for const char* pointers, which is to print the (presumably) null terminated string pointed to by that pointer.
Bottom line: Pointers that are not char* will be printed as pointers. Pointers that are char* will be printed as a string.

Function that will act like an Strlen C++

I want to make a function that will do the same as Strlen does, andI get the error: "string subscript out of range". I tried fixing it but has no idea.
heres the code:
#include "stdafx.h"
#include "stdafx.h"
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int strlen1( string str)
{
int count=0;
int i=0;
while (str[i]!='\0')
{
count++;
i++;
}
return count;
}
int _tmain(int argc, _TCHAR* argv[])
{
string input;
cin >> input;
cout << strlen1(input) << endl;
return 0;
}
thanks!
In short, for a non-const std::stringaccessing an element beyond the string length has Undefined Behavior (more precisely, when using the non-const operator[] for that).
C++98 §21.3.4/1, about std::string::operator[]:
If pos < size, returns data()[pos]. Otherwise, if pos == size(), the const version returns charT(). Otherwise the behavior is undefined.
And your string is non-const.
You can make it const, which will then invoke a special provision in the standard that guarantees zero result for element n, but that does not address the problem that your function is completely redundant for std::string.
Perhaps you mean to have argument type char const*.
That would make more sense, and then also the function would work.
Cheers & hth.,
You seem to be under the misconception that std::string is the same as a C-style string (char const*). This is simply not true. There is no null terminator.
Here's your strlen function the only way it will work:
int strlen1(string str) { return static_cast<int>(str.size()); }
std::string has a nice size() method for this.
strlen is based on zero terminated strings (char*, or char arrays), C++ string are based on length + data, you can't access to data after the end of string (where a terminal zero would be). Beside that, getting the length is a standard property of C++ strings (size()), hence the standard way of writing strlen is just to call size.