I saved some user information in .txt file. every time when application launches it checks some specific things, like device id is same as saved or not? 2 type of returns are possible from device id with some character differences.
if i saved this string "pWch7r1fzu tILmQIMjIylBZxJk=" in txt file. i want to make this accepted by application if device id return this string "pWch7r1fzu+tILmQIMjIylBZxJk=" or this string "pWch7r1fzu tILmQIMjIylBZxJk=".
clearly, i have no idea how to achieve this. i have tried index of and instr. they are seems to be fine. like if string matches its return zero and if not -1.
but if device id is this "hfhejkfnenknBG+hhhh" it's returns -1 as well. i do not want it to accept by application.
finally what i want is to get exact string. differences of one or two char is okay not more than that.
In this case string a being the given string and b being the to be matched string.
string a = "abcdefghi";
string b = "abcdefghi";
char[] c = a.ToCharArray();
char[] d = b.ToCharArray();
if(b.Take(b.Length).SequenceEqual(a))
{
// success
}
Related
I am building an avr program with many wchar_t strings. At the moment the way I store them in to the chip is this:
const _flash wchar_t* const Greek_text[] =
{
[ACCELERATION_TEXT] = (const _flash wchar_t[]) {L"Επιταγχυνση"},
[ACCELERATION_SHORT_TEXT] = (const _flash wchar_t[]) {L"Επιταγχ."},
[REDUCED_TEXT] = (const _flash wchar_t[]) {L"Μειωμενη"},
[FULL_TEXT] = (const _flash wchar_t[]) {L"Μεγιστη"}
}
I am looking for a way to store them while being compressed. One way that I can think of, is removing the Unicode prefix for the specific language, but the only way of doing this to my knowledge, is storing the lower half of each word manually in unsigned chars. Is there a more practical way of doing something like this?
It looks like all your strings are Greek. You could assign each letter or character that appears in your strings to a number between 1 and 255 and then just have char strings where each char contains one of those encoded numbers. This would halve the space of each individual string, but you might need a lookup table in your program to convert those codes back to unicode, and that table could occupy up to 512 bytes in your program memory depending on how many different characters you use.
People have already developed encodings like this before, so maybe you could just use a standard one, like Windows-1253.
Figuring out a good system to author these encoded strings and insert them into your program is another challenge. I'd suggest writing a simple Ruby program like the one below. (You'd save the program itself as a UTF-8 text file on your computer and edit it using a standard text editor.)
string_table = {
ACCELERATION_TEXT: 'Επιταγχυνση',
ACCELERATION_SHORT_TEXT: 'Επιταγχ.',
REDUCED_TEXT: 'Μειωμενη',
FULL_TEXT: 'Μεγιστη',
}
string_table.each do |key, value|
hex = value.encode('Windows-1253').each_byte.map { |b| '\x%02x' % b }.join
puts "[#{key}] = \"#{hex}\","
end
The program above outputs this:
[ACCELERATION_TEXT] = "\xc5\xf0\xe9\xf4\xe1\xe3\xf7\xf5\xed\xf3\xe7",
[ACCELERATION_SHORT_TEXT] = "\xc5\xf0\xe9\xf4\xe1\xe3\xf7\x2e",
[REDUCED_TEXT] = "\xcc\xe5\xe9\xf9\xec\xe5\xed\xe7",
[FULL_TEXT] = "\xcc\xe5\xe3\xe9\xf3\xf4\xe7",
Also, another way to maybe save space (while increasing CPU time used) would be to get rid of the array of pointers you are creating. This would save two bytes per string. Just store all the strings next to each other in memory. The strings would be separated by null characters and you can optionally have a double null character marking the end of the table. To look up a string in the table, you start reading bytes from the beginning of the table one at a time and count how many null characters you have seen.
const _flash char greek_text[] =
"\xc5\xf0\xe9\xf4\xe1\xe3\xf7\xf5\xed\xf3\xe7\0"
"\xc5\xf0\xe9\xf4\xe1\xe3\xf7\x2e\0"
"\xcc\xe5\xe9\xf9\xec\xe5\xed\xe7\0"
"\xcc\xe5\xe3\xe9\xf3\xf4\xe7\0";
I'm trying to read user login data (username, password, some integer, security answer) from a file and store it in a linked list. The file validation.txt holds the data for all users, where each user has a line of its own holding all of the fields for that user in the format (no spaces):
user1_$_ password1 _$_42 _$_answer1
user2_$_ password2 _$_21 _$_answer2
The various fields are to be stored as members of a struct (named 'user') that comprises the linked list (each struct also has a member "next" which points to the next user in the list.
I trying to use fscanf to parse each line and save the info directly into the structs, but for some reason, the fscanf doesn't pick up on $ when it reaches them, and stores an entire line under the "username" member rather than just the string "user1". I have read loads online about the string format but can't figure this out. I played around trying to add whitespaces to the file and to the format string with many different outcomes that I didn't really understand why they are the way they are.. Based on what I read online the string should be read until a character present in the format string is reached, and it is then skipped over. This seems pretty straightforeward but why doesn't this work ?
My code:
user *loadUsers(){
user *Users, *currPtr;
FILE *fp = fopen("validation.txt", "r");
if(fp==NULL||feof(fp)!=0){
return NULL;
}
Users = (user *)malloc(sizeof(user));
currPtr = Users;
fscanf(fp, "%s_$_%s_$_%d_$_%s\n", currPtr->username, currPtr->password, &(currPtr->randomNum), currPtr->secAns);
while(feof(fp)==0){
currPtr->next = (user *)malloc(sizeof(user));
currPtr = currPtr->next;
fscanf(fp, "%s_$_%s_$_%d_$_%s\n", currPtr->username, currPtr->password, &(currPtr->randomNum), currPtr->secAns);
}
return Users;
}
Output:
When I iterate through my list after the call to this function and print just the username members of each struct, I get the whole line printed (username = user1_$_ password1 _$_42 _$_answer1 rather than just user1). Anyone know what's going on here ?
Never, ever, call *scanf() without checking the return value.
%s matches any sequence of non-whitespace characters, i.e. fscanf() keeps matching that first %s and does not even "see" the following underscore in the format string.
You could work with %[^_] to match everything not an underscore, but generally speaking you are better off reading whole lines of input with fgets() and then parse the input in memory using the various string functions. *scanf() is rather limited in its ability to recover from malformed input.
I'm going to make a weather program, so I need to parse an XML file.
I've installed a libxml(in fact, it was installed)
However, I don't know how to parse a number.
Here is part of my XML code:
<tmx>-999.0</tmx>
<tmn>-999.0</tmn>
<sky>2</sky>
<pty>0</pty>
and I need a number in the last line; 'pty'
Thank you very much for helping me.
Considering you might not need libXML just to extract a few value, and as long as you don't care about the validity of your input, you could load the file in memory ( or part of it ).
char* xmlChunk; // your data will be stored inside
char* tagStartBegin = strstr(xmlChunk,"<pty");
char* tagStartEnd = strstr(tagStartBegin,">");
char* value = tagStartEnd+1;
// get the end tag
char* tagEndBegin = strstr(tagStartEnd,"</pty>");
//end the string here
*tagEndBegin = '\0';
// parse your value
doSomeThing(value);
You might need to adapt your code for unicode input if any
I have an Arduino project with a string, called string, which is four digits, each between 0 and 9. So for example, a possible value is 1200. I'd like to take the first character, 1, and assign it to another string, called xCo.
String string = String(c);
String xCo = String(string[0]);
Serial.print(xCo);
Strangely, the Serial.print(xCo); line doesn't just print the first character, 1. Rather, it prints the whole string. I've read other questions' answers and they said that to reference a particular character, you just choose the index number of that character by doing something like string[0]. Yet, this isn't working for me.
What am I doing wrong here?
Edit: As the commenters have pointed out, String is an Arduino type, at least I'm pretty sure. My C and Arduino experience is very limited, so I can't be sure.
If you need to get the value of a character at a given position in a string, use charAt().
String string = "1200";
char singleCharacter = string.charAt(0);
Serial.print(singleCharacter);
Lot of people recommends to not use String. The best way is to simply use char *
char *foo = "1200";
char c = foo[0];
I want to delete a file into recycle bin. I using this code.
SHFILEOPSTRUCT FileOp;
FileOp.hwnd = NULL;
FileOp.wFunc=FO_DELETE;
FileOp.pFrom= lpFileName; //it's my value \\?\C:\WorkFolder\qweqw.docx
FileOp.pTo = NULL;
FileOp.fFlags=FOF_ALLOWUNDO|FOF_NOCONFIRMATION;
FileOp.hNameMappings=NULL;
int t_res = SHFileOperation(&FileOp); // t_res = 124
return t_res;
What's i doing wrong? Thanks in advance.
What is t_res, it should give the error code and suggest the reason
Note that pFrom takes files, not single file, so you should terminate the buffer with two zeros, see doc excerpt from MSDN:
Although this member is declared as a single null-terminated string,
it is actually a buffer that can hold multiple null-delimited file
names. Each file name is terminated by a single NULL character. The
last file name is terminated with a double NULL character ("\0\0") to
indicate the end of the buffer.
The error code is, according to the documentation:
DE_INVALIDFILES 0x7C The path in the source or destination or both was invalid.
You don't mention any analysis of this, so my suggestion would be to dig into how the filename is represented. Is it the proper encoding?