copy string with offsett C++ - c++

i need help to copy string with offset and invert
how i implement this function ?
void copyString(char *input, int offset, int length, bool invert, char *output, int output_offset)
input : input string
offset : starting position to be copied.
length : length of substring of input to be copied.
invert : the result would be inverted if true.
output : result string.
output_offset : starting position of output to receive the copied string
example
st ="Hello World";
st2="My Name is Fatima";
copyString(st,6,5,true,st2,11) -> st2 = "My Name is dlrow";
i have succes with copystring function without offset and invert..
this my function
void stringcpy(const char* src,char* dest)
{
while(*src != '\0')
{
*dest++ = *src++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
const char str[] = "fatima";
char str2[sizeof(str)] ;
const char* s = str;
char* s2 = str2;
stringcpy(s, s2);
cout<<str2<<"\n";
cout<<str<<"\n";
system("pause");
}
anyone can help ?

Related

Why does my char* copier return different things?

Writing a simple string copier and testing it in the main() fucntion. What's odd is that sometimes the program returns
"HelloHello"
like it should, but maybe every third time I run it, the program prints out:
"Hello!Hello!▌▌▌▌▌▌▌▌▌▌▒"UòB╚"
Why is the tail of garbage data only sometimes being added to the end of my second string?
#include <iostream>
using namespace std;
int strlength(const char* c)
{
int size = 0;
while (*c) {
++c;
++size;
}
return size;
}
char* mystrdup(const char* c)
{
int size = strlength(c);
char* result = new char;
copy(c, c + size, result);
return result;
}
void print_array(const char* c)
{
int size = strlength(c);
while (*c) {
cout << *c;
++c;
}
}
int main()
{
char test[] = "Hello!";
char* res = mystrdup(test);
print_array(test);
print_array(res);
}
The program has undefined behavior because you are allocating not enough memory for the result string.
char* mystrdup(const char* c)
{
int size = strlength(c);
char* result = new char;
^^^^^^^^^^^^^^^^^^^^^^^
copy(c, c + size, result);
return result;
}
Moreover you are not copying the terminating zero to the result string.
At least the two functions strlength and mystrdup can look the following way
size_t strlength( const char *s )
{
size_t size = 0;
while ( s[size] ) ++size;
return size;
}
char * mystrdup( const char *s )
{
size_t size = strlength( s ) + 1;
char *result = new char[size];
copy( s, s + size, result );
return result;
}
Of course instead of the standard algorithm std::copy you could use the standard C function strcpy declared in the header <cstring>.
strcpy( result, s );
And do not forget to delete the allocated array.
char* res = mystrdup(test);
//…
delete [] res;
Pay attention to that the function print_array does not use the variable size. There is no need to output a C-string character by character.
The function could be defined like
std::ostream & print_array( const char *s, std::ostream &os = std::cout )
{
return os << s;
}
And at last the identifier c is usually used with single objects of the type char. If you deal with a string then it is better to use the identifier s.
You have multiple bugs in your code. You allocate wrong memory (char instead of char array). You don't delete the memory. Stop using C-string and use std::string
#include <iostream>
#include <string>
using std::cout;
void print_array(const char* c)
{
while (*c) {
cout << *c;
++c;
}
}
int main()
{
std::string = "Hello!";
std::string res = test;
print_array(test.c_str());
print_array(res.c_str());
}
In strcpy you need to create a char size.
char* mystrdup(const char* c)
{
int size = strlength(c);
char* result = new char[size];
copy(c, c + size, result);
return result;
}

C++ get number of char* in char**

So I have the following function, which splits the char* input by spaces and adds each char* to a char** which is finally returned.
char **split_input(char *input) {
char **command = (char **)malloc(8 * sizeof(char *));
const char *separator = " ";
char *parsed;
int index = 0;
parsed = strtok(input, separator);
while (parsed != NULL) {
command[index] = parsed;
index++;
parsed = strtok(NULL, separator);
}
command[index] = NULL;
return command;
}
I was wondering if there is any way of getting the amount of char* that the returned char** contains.
I was wondering if there is any way of getting the amount of char* that the returned char** contains.
Given the code you have shown, there is only 1 way - the caller will have to iterate the array counting elements until it reaches the NULL at the end.
Otherwise, tweak the function to return the array count alongside the array pointer, either as an optional output parameter, or use a std::pair<char**, int> or struct { char**; int; } as the return value.

How to imitate std::string's find_first_not_of using strspn

I'm trying to create a custom string class similar to std::string.
And I'm having a trouble implementing 'find_first_not_of'.
Here's my test code
#include <iostream>
class String {
private:
char *m_data;
int m_length;
char *alloc(int size);
int length() const {return m_length;}
int size() const {return m_length;}
const char *c_str() const {return m_data;}
public:
String(const char *str=0);
int find_first_not_of(const char *str);
static const int npos;
};
const int String::npos = -1;
char * String::alloc(int size)
{
char * str = new char[size+1];
return str;
}
String::String(const char *str)
{
if (!str) str = "";
m_length = static_cast<int>(strlen(str));
m_data = alloc(m_length);
strcpy(m_data, str);
}
int String::find_first_not_of(const char *str)
{
size_t len = strspn(c_str(), str);
if (len == 0)
return -1;
else
return len;
}
int main(int argc, const char * argv[]) {
String A = "123";
std::string B = "123";
if (A.find_first_not_of("0123456789") == -1)
std::cout << "A is digit" << std::endl;
else
std::cout << "A is not digit" << std::endl;
if (B.find_first_not_of("0123456789") == -1)
std::cout << "B is digit" << std::endl;
else
std::cout << "B is not digit" << std::endl;
return 0;
}
And this is the result I see if I run the code.
A is not digit
B is digit
Program ended with exit code: 0
Can someone please point me what I'm missing?
Thanks!
You are confusing your String::find_first_not_of with std::string::find_first_not_of. They are different functions that have different functionality.
I really don't understand what String::find_first_not_of needs to do, but here is what each of them returns (one the length of the string and the other one the position):
std::string::find_first_if_not (from here):
The position of the first character that does not match.
If no such characters are found, the function returns string::npos.
strspn (from here):
The length of the initial portion of str1 containing only characters that appear in str2.
Therefore, if all of the characters in str1 are in str2, the function returns the length of the entire str1 string, and if the first character in str1 is not in str2, the function returns zero.
So even the inner working of the functions are different.
You should be able to follow based on this info.
This one worked just like std::string's find_first_not_of.
int String::find_first_not_of(const char *str, int pos)
{
const int len = static_cast<int>(strspn(c_str() + pos, str));
if (len + pos == m_length)
return -1; //npos
else
return len + pos;
}
#Garmekain's explanation was really helpful. Thank you.

EXC_BAD_ACCESS occurred when assign char with a poitner

EXC_BAD_ACCESS occurred in *str++ = *end;. What's wrong with this?
#include <iostream>
using namespace std;
int main() {
char *hello = "abcdefgh";
char c = 'c';
char *str = hello;
//printf("%s",str);
char * end = str;
char tmp;
if (str) {
while (*end) {
++end;
}
--end;
while (str < end) {
tmp = *str;
printf("hello:%s str:%c, end:%c\n", hello, *str, *end);
*str++ = *end;
*end-- = tmp;
}
}
return 0;
}
It is undefined behavior to attempt to alter a string literal. Change your code to the equivalent below, and you will see the issue:
const char *hello = "abcdefgh";
const char *str = hello;
const char * end = str;
So do you see why the line *str++ = *end; had a problem? You're attempting to write to a const area, and you can't do that.
If you want an even simpler example:
int main()
{
char *str = "abc";
str[0] = 'x';
}
Don't be surprised if this simple program produces a crash or segmentation fault when the
str[0] = 'x';
line is executed.
Unfortunately, string-literals did not have to be declared as const char* in C, and C++ brought this syntax over. So even though it looks like you are not using const, you are.
If you want the code to actually work, declare a writeable buffer, i.e. an array of char:
char hello[] = "abcdefgh";
char str[100];
strcpy(str, hello);
char end[100];
strcpy(end, str);
It seems like you're trying to reverse the string. It also looks like you're overcomplicating things.
C-style strings declared on the stack have to be declared as const char *, which means you can't change the characters as they are constant.
In C++ we use strings, and string iterators:
#include <iostream>
#include <string>
using std::string;
using std::reverse;
using std::swap;
using std::cout;
using std::endl;
int main(int argc, const char * argv[])
{
string hello("abcdefgh");
reverse(hello.begin(), hello.end());
cout << hello << endl;
return 0;
}
Manually:
static void reverse(std::string & str)
{
string::size_type b = 0, e = str.length() - 1, c = e / 2;
while(b <= c)
{
swap(str[b++], str[e--]);
}
}
Recursively:
static void reverse_helper(std::string & str,
string::size_type b,
string::size_type e)
{
if(b >= e)
return;
swap(str[b], str[e]);
reverse_helper(str, ++b, --e);
}
static void reverse(std::string & str)
{
reverse_helper(str, 0, str.length() - 1);
}

using strstr() function is breaking

I am using strstr() function but I am getting the crash.
This part of code is crashing with error "Access violation reading location 0x0000006c."
strstr(p_czCharactersToDelete, (const char*)p_czInputString[index]))
Here is the complete code...
#include "stdafx.h"
#include <iostream>
#include <string>
void delchar(char* p_czInputString, const char* p_czCharactersToDelete)
{
for (size_t index = 0; index < strlen(p_czInputString); ++index)
{
if(NULL != strstr(p_czCharactersToDelete, (const char*)p_czInputString[index]))
{
printf_s("%c",p_czInputString[index]);
}
}
}
int main(int argc, char* argv[])
{
char c[32];
strncpy_s(c, "life of pie", 32);
delchar(c, "def");
// will output 'li o pi'
std::cout << c << std::endl;
}
The prototype of strstr() is as follows,
char * strstr ( char * str1, const char * str2 );
The function is used to locate substring from a main string. It returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
In your case you are passing the wrong parameters to the strstr(). You are calling,
strstr(p_czCharactersToDelete, (const char*)p_czInputString[index]));, which is wrong. Because the pointer p_czCharactersToDelete points to the sub string constant and p_czInputString points to the main string. Call strstr() as strstr(p_czInputString, p_czCharactersToDelete); and make corresponding changes in the function delchar().
you are using the wrong strstr.
probably you need strchr or strpbrk.
#include <cstring>
#include <algorithm>
class Include {
public:
Include(const char *list){ m_list = list; }
bool operator()(char ch) const
{
return ( strchr(m_list, ch) != NULL );
}
private:
const char *m_list;
};
void delchar(char* p_czInputString, const char* p_czCharactersToDelete){
Include inc(p_czCharactersToDelete);
char *last = std::remove_if(p_czInputString, p_czInputString + strlen(p_czInputString), inc);
*last = '\0';
}