Reputation: 3557
I'm going to try to explain the problem.
I am getting a string containing a registry key. For example:
HKEY_CURRENT_USER\Software\MyProgram\SomeOtherValue\SomeKey
now, I need to parse that string into 3 different char (or char *) variables. After the parsing it'll be something like:
string1 = HKEY_CURRENT_USER
string2 = \Software\MyProgram\SomeOtherValue\ /* with the '\' */
string3 = SomeKey
Not only do I need to group the backslashes; I also don't know how many of them are there. I could have something like:
HKEY_CURRENT_USER\Software\SomeKey
or something like:
HKEY_CURRENT_USER\Software\SomeValue\SomeOthervalue\Someblah\SomeKey
I tried with strtok()
and strcspn()
but i'm getting very confused here...
Any idea how to get this done?
Code is appreciated.
Thanks!
Upvotes: 1
Views: 1270
Reputation: 10490
Copy the string into an allocated one and split the variable placing a '\0' in the slash where you want to truncate it.
You can "scan" the string for slashes using the strchr function.
void to_split(char *original, int first_slash, int second_slash, char **first, char **second, char **third) {
int i;
char *first_null;
char *second_null;
char *allocated;
if (first_slash >= second_slash)
return;
allocated = malloc(strlen(original) + 1);
*first = allocated;
strcpy(allocated, original);
for (i = 0, first_null = allocated; i < first_slash && (first_null = strchr(first_null,'\\')); i++);
if (first_null) {
*first_null = '\0';
*second = first_null + 1;
}
second_null = allocated + strlen(original);
i = 0;
while (i < second_slash && second_null > allocated)
i += *second_null-- == '\\';
if (++second_null > allocated) {
*second_null = '\0';
*third = second_null + 1;
}
}
Usage:
int main (int argc, char **argv) {
char *toSplit = "HKEY_CURRENT_USER\\Software\\MyProgram\\SomeOtherValue\\SomeKey";
char *first;
char *second;
char *third;
to_split(toSplit, 1, 3, &first, &second, &third);
printf("%s %s %s\n", first, second, third);
return 0;
}
It isn't the best code in the world, but it gives you an idea.
Upvotes: 2
Reputation: 4230
strchr(char*, char) : locate first occurrence of char in string
strrchr(char*, char) : locate last occurrence of char in string
char* str = "HKEY_CURRENT_USER\Software\MyProgram\SomeOtherValue\SomeKey";
char token1[SIZE], token2[SIZE], token3[SIZE];
char* first = strchr(str, '\\');
char* last = strrchr(str, '\\')+1;
strncpy(token1, str, first-str);
token1[first-str] = '\0';
strncpy(token2, first, last-first);
token2[last-first] = '\0';
strcpy(token3, last);
We use strchr to find the first '\', and strrchr to find the last '\'. We then copy to token1, token2, token3 based on those positions.
I decided to just use fixed size buffers instead of calloc-ing, because that's not so important to illustrate the point. And I kept messing it up. :)
Upvotes: 2
Reputation: 64682
Pseudo-Code:
Step 1: Scan forward until the first "\", note the index.
Step 2: Scan Backward from the end to the last "\" (the first "\" encountered when going backwards), note the index.
Step 3: StrCpy the relevant pieces out into 3 strings.
Code: (does not rely on strrchr, or other methods you seem to have issues with)
void ParseRegEntry(char* regKey, char** TopLevel, char** Path, char** Key);
int main(void)
{
char* regKey = "HKEY_CURRENT_USER\\Software\\MyProgram\\SomeOtherValue\\SomeKey";
char* TopLevel;
char* Path;
char* Key;
ParseRegEntry(regKey, &TopLevel, &Path, &Key);
printf("1: %s\n2: %s\n3: %s\n", TopLevel, Path, Key);
free(TopLevel);
free(Path);
free(Key);
return 0;
}
void ParseRegEntry(char* regKey, char** TopLevel, char** Path, char** Key)
{
int firstDelimiter = 0;
int lastDelimiter = strlen(regKey)-1;
int keyLen;
while(regKey[firstDelimiter] != '\\')
{
firstDelimiter++;
}
while(regKey[lastDelimiter] != '\\')
{
lastDelimiter--;
}
keyLen = strlen(regKey) - lastDelimiter-1;
*TopLevel = (char*)malloc(firstDelimiter+1);
strncpy(*TopLevel, regKey, firstDelimiter);
(*TopLevel)[firstDelimiter] = '\0';
*Path = (char*)malloc(lastDelimiter - firstDelimiter+2);
strncpy(*Path, regKey+firstDelimiter, lastDelimiter - firstDelimiter);
(*Path)[lastDelimiter-firstDelimiter] = '\0';
*Key = (char*)malloc(keyLen+1);
strncpy(*Key, regKey+lastDelimiter+1, keyLen);
(*Key)[keyLen] = '\0';
}
Upvotes: 2
Reputation: 412
Here's an example using strchr and strrchr to scan forwards and backwards in the string for the '\'.
char str[] = "HKEY_CURRENT_USER\Software\MyProgram\SomeOtherValue\SomeKey";
char *p, *start;
char root[128], path[128], key[128];
p = strchr (str, '\\');
strncpy (root, str, p - str);
start = p;
p = strrchr (str, '\\') + 1;
strncpy (path, start, p - start);
strcpy (key, p);
Upvotes: 1