C++ Hex search in std:string failed - c++

I have an std:string. I would like to find the pattern "0x789c" in hexadecimal.
According another thread in stackoverflow, i have done this :
int nPosD = buffer.find("\x78\x9C");
and tried
int nPosD = buffer.find(std::string("\x78\x9C"),2);
No success !The return is -1 !My pattern 0x789c is in my string ! I have tested it with HexEdit software.
Anyone have idea for this ?
Thanks a lot :)
best regards,

int nPosD = buffer.find(std::string("\x78\x9C"),2);
will look for the string "\x78\x9c" starting at the 3rd character (offset 2) in buffer. If it does not appear at or after that point, it will return -1. If you want to search the entire string from the beginning, get rid of the 2

The following works for me:
char data[] = {'A', 0x78, 0x9C};
string buffer(data, 3);
cout << buffer.find("\x78\x9C") << endl;
It prints "1" as it should. It works as well without the initial A. You have probably set your string wrong. It may contain '0x789c' in ascii instead of binary, in which case you want to do find("0x789c").

Related

C++ Recognize UTF-8 or Hebrew languague

I'm working on some code that his target it recognize if the strings equal
Have two type of string - string 1 came from text file , string 2 came from server side from chat packet
i try very different options , this my last trying but nothing success the sentence not recognize has equal at all for example this string on text file "בדיקה" and the string that came from packet side is "בדיקה" too and still nothing equal
`
if(gSentenceEvent.IsRunning())
{
std::string s = lpMsg->message;
int Len = strlen(gSentenceEvent.RandomSentence);
std::string str;
str.assign(gSentenceEvent.RandomSentence, gSentenceEvent.RandomSentence + Len);
if (str.compare(s) == 0)
{
gSentenceEvent.SetRunning(false);
gNotice.GCNoticeSendToAll(0,0,0,0,0,0,gMessage.GetMessage(1130));
gNotice.GCNoticeSendToAll(0,0,0,0,0,0,gMessage.GetMessage(1127),lpObj->Name);
}
else
{
gNotice.GCNoticeSendToAll(0,0,0,0,0,0,"%s Try %s\n",lpObj->Name,s);
gNotice.GCNoticeSendToAll(0,0,0,0,0,0,"Answer Is %s\n",str);
}
}
`
if someone have any idea for solving the issue i will be happy to hear some ways that recognize it well
Thanks in advance !
trying convert the text for wstring as well but still nothing
when i check the hex value of both sentence even they equal
gNotice.GCNoticeSendToAll(0,0,0,0,0,0,"%.2X",lpMsg->message);
gNotice.GCNoticeSendToAll(0,0,0,0,0,0,"%.2X",gSentenceEvent.RandomSentence);
that really came different from example "בדיקהה 3" On both sides
ServerSide = 22B6970
TextFile = D9C0B0

How could I copy data that contain '\0' character

I'm trying to copy data that conatin '\0'. I'm using C++ .
When the result of the research was negative, I decide to write my own fonction to copy data from one char* to another char*. But it doesn't return the wanted result !
My attempt is the following :
#include <iostream>
char* my_strcpy( char* arr_out, char* arr_in, int bloc )
{
char* pc= arr_out;
for(size_t i=0;i<bloc;++i)
{
*arr_out++ = *arr_in++ ;
}
*arr_out = '\0';
return pc;
}
int main()
{
char * out= new char[20];
my_strcpy(out,"12345aa\0aaaaa AA",20);
std::cout<<"output data: "<< out << std::endl;
std::cout<< "the length of my output data: " << strlen(out)<<std::endl;
system("pause");
return 0;
}
the result is here:
I don't understand what is wrong with my code.
Thank you for help in advance.
Your my_strcpy is working fine, when you write a char* to cout or calc it's length with strlen they stop at \0 as per C string behaviour. By the way, you can use memcpy to copy a block of char regardless of \0.
If you know the length of the 'string' then use memcpy. Strcpy will halt its copy when it meets a string terminator, the \0. Memcpy will not, it will copy the \0 and anything that follows.
(Note: For any readers who are unaware that \0 is a single-character byte with value zero in string literals in C and C++, not to be confused with the \\0 expression that results in a two-byte sequence of an actual backslash followed by an actual zero in the string... I will direct you to Dr. Rebmu's explanation of how to split a string in C for further misinformation.)
C++ strings can maintain their length independent of any embedded \0. They copy their contents based on this length. The only thing is that the default constructor, when initialized with a C-string and no length, will be guided by the null terminator as to what you wanted the length to be.
To override this, you can pass in a length explicitly. Make sure the length is accurate, though. You have 17 bytes of data, and 18 if you want the null terminator in the string literal to make it into your string as part of the data.
#include <iostream>
using namespace std;
int main() {
string str ("12345aa\0aaaaa AA", 18);
string str2 = str;
cout << str;
cout << str2;
return 0;
}
(Try not to hardcode such lengths if you can avoid it. Note that you didn't count it right, and when I corrected another answer here they got it wrong as well. It's error prone.)
On my terminal that outputs:
12345aaaaaaa AA
12345aaaaaaa AA
But note that what you're doing here is actually streaming a 0 byte to the stdout. I'm not sure how formalized the behavior of different terminal standards are for dealing with that. Things outside of the printable range can be used for all kinds of purposes depending on the kind of terminal you're running... positioning the cursor on the screen, changing the color, etc. I wouldn't write out strings with embedded zeros like that unless I knew what the semantics were going to be on the stream receiving them.
Consider that if what you're dealing with are bytes, not to confuse the issue and to use a std::vector<char> instead. Many libraries offer alternatives, such as Qt's QByteArray
Your function is fine (except that you should pass to it 17 instead of 20). If you need to output null characters, one way is to convert the data to std::string:
std::string outStr(out, out + 17);
std::cout<< "output data: "<< outStr << std::endl;
std::cout<< "the length of my output data: " << outStr.length() <<std::endl;
I don't understand what is wrong with my code.
my_strcpy(out,"12345aa\0aaaaa AA",20);
Your string contains character '\' which is interpreted as escape sequence. To prevent this you have to duplicate backslash:
my_strcpy(out,"12345aa\\0aaaaa AA",20);
Test
output data: 12345aa\0aaaaa AA
the length of my output data: 18
Your string is already terminated midway.
my_strcpy(out,"12345aa\0aaaaa AA",20);
Why do you intend to have \0 in between like that? Have some other delimiter if yo so desire
Otherwise, since std::cout and strlen interpret a \0 as a string terminator, you get surprises.
What I mean is that follow the convention i.e. '\0' as string terminator

sscanf for this type of string

I'm not quite sure even after reading the documentation how to do this with sscanf.
Here is what I want to do:
given a string of text:
Read up to the first 64 chars or until space is reached
Then there will be a space, an = and then another space.
Following that I want to extract another string either until the end of the string or if 8192 chars are reached. I would also like it to change any occurrences in the second string of "\n" to the actual newline character.
I have: "%64s = %8192s" but I do not think this is correct.
Thanks
Ex:
element.name = hello\nworld
Would have string 1 with element.name and string2 as
hello
world
I do recommend std::regex for this, but apart from that, you should be fine with a little error checking:
#include <cstdio>
int main(int argc, const char *argv[])
{
char s1[65];
char s2[8193];
if (2!=std::scanf("%64s = %8192s", s1, s2))
puts("oops");
else
std::printf("s1 = '%s', s2 = '%s'\n", s1, s2);
return 0;
}
Your format string looks right to me; however, sscanf will not change occurences of "\n" to anything else. To do that you would then need to write a loop that uses strtok or even just a simple for loop evaluating each character in the string and swapping it for whatever character you prefer. You will also need to evaluate the sscanf return value to determine if the 2 strings were indeed scanned correctly. sscanf returns the number of field successfully scanned according to your format string.
#sehe shows the correct usage of sscanf including the check for the proper return value.

C++ search a string

I am having a really hard time with this problem...
Write a program that reads two strings (that do not contain blanks)
called searchPattern and longSequence.
The program will display in the screen the positions where
searchPattern appears in longSequence.
For example, when
seachPattern is asd
and longSewuence is asdfasdfasdfasdf
(the positions are 0123456789012345)
the program will display 0, 4, 8, 12.
Another example, when
seachPattern is jj
and longSewuence is kjlkjjlkjjjlkjjjkl
(the positions are 012345678901234567)
the program will display 4, 8, 9, 13, 14.
can anyone help?
Some hints:
Read in the two strings. Look up "std::cin" for how to read and "std::string" for how to store the strings.
Look at the std::string class's find() method to search for the substring in the long string.
Have a go and then post what you have done on here. You will find plenty of people happy to help you, but you have to make some effort yourself. :-)
As a starting point, maybe just write the part that reads in the strings. When that is working well, you can add features.
Good luck.
To start thinking about the solution of problems like this, the best way is to think how you would solve it using a pen and paper in as much detail as possible and then try to translate that to code.
I would use Test Driven Development and start out small and build up.
For example, forget about user I/O, and stick with hard-coded data:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
int main(void) // For now, can be modified later.
{
const char pattern[] = "asd";
const char sequence[] = "asdfasdfasdfasdf";
std::string::size_type position = 0;
const std::string longSequence(sequence);
position = longSequence.find(pattern, position);
while (position != std::string::npos)
{
cout << "pattern found at position: " << position << endl;
position = longSequence.find(pattern, position);
}
cout << "Paused. Press ENTER to continue." << endl;
cin.ignore(100000, '\n');
return 0;
}
You may want to convert the above into using a state machine rather than using std::string::find(). Again, this is just a foundation to build upon.
It's a recursive backtracking problem. Just like getting the mouse out of the maze. Define your base cases and your paths through the data. In the end all you need is a single function of maybe 15 - 20 lines.

How to check the length of an input? (C++)

I have a program that allows the user to enter a level number, and then it plays that level:
char lvlinput[4];
std::cin.getline(lvlinput, 4)
char param_str[20] = "levelplayer.exe "
strcat_s(param_str, 20, lvlinput);
system(param_str);
And the level data is stored in folders \001, \002, \003, etc., etc. However, I have no way of telling whether the user entered three digits, ie: 1, 01, or 001. And all of the folders are listed as three digit numbers. I can't just check the length of the lvlinput string because it's an array, so How could I make sure the user entered three digits?
Why not use std::string?
This makes storage, concatenation, and modification much easier.
If you need a c-style string after, use: my_string.c_str()
Here is a hint: To make your input 3 characters long, use std::insert to prefix your number with 0's.
You are really asking the wrong question. Investigate the C++ std::string class and then come back here.
Eh? Why do they need to enter 3 digits? Why not just pad it if they don't? If you really want to check that they entered 3 digits, use strlen. But what I recommend you do is atoi their input, and then sprintf(cmd, "levelplayer.exe %03d", lvlinput_as_integer)
Here's how you could do this in C++:
std::string lvlinput;
std::getline(std::cin, lvlinput);
if (lvlinput.size() > 3) { // if the input is too long, there's nothing we can do
throw std::exception("input string too long");
}
while (lvlinput.size() < 3) { // if it is too short, we can fix it by prepending zeroes
lvlinput = "0" + lvlinput;
}
std::string param_str = "levelplayer.exe ";
param_str += lvlinput;
system(param_str.c_str());
You've got a nice string class which takes care of concatenation, length and all those other fiddly things for you. So use it.
Note that I use std::getline instead of cin.getline. The latter writes the input to a char array, while the former writes to a proper string.
What do you mean you can't check the length of the string? getline generates a NULL terminated c-string so just use strlen(lvlinput).
Neil told you where you should start, your code might look like this.
std::string level, game = "levelplayer.exe ";
std::cout << "Enter the level number : ";
std::cin >> level;
if(level.size() != 3)
{
// Error!
}
else
{
// if you have more processing, it goes here :)
game += level;
std::system(game.c_str());
}
You can check the length of your NULL terminated string that getline returns by using:
int len = strlen(lvlinput);
This works because getline returns a NULL-terminated string.
However, this is besides the point to your problem. If you want to stay away from std::string (and there isn't any particular reason why you should in this case), then you should just convert the string to an integer, and use the integer to construct the command that goes to the system file:
char lvlinput[4];
std::cincin.getline(lvlinput, 4);
char param_str[20];
snprintf(param_str, 20, "levelplayer.exe %03d", atoi(lvlinput));
system(param_str);