Finding a string inside string


A

arnuld

Program works fine. I know there are improvements left to be done but
they unidentified by as of now. Help will be appreciated as usual :).
2nd, any strange values that can crash this program and how to avoid them.


/* A program to save input. Input is a character string of key=value
pairs separated by a separator. e.g "name=clc,messages=100".
* We will write a program which will save value when provided with a
belonging key.
*
* VERSION 0.0
*/

#include <stdio.h>
#include <string.h>


enum {
SIZE_VALUE = 20
};


int get_value_using_key(const char* s, const char* k, const int lenk,
char* v, const int lenv);

int main(void)
{
const char* arr = "group=,messages=";
const char* key = "group";

char value[SIZE_VALUE+1] = {0};
int ret;



printf("input: %s\n", arr);
ret = get_value_using_key(arr, key, strlen(key), value, SIZE_VALUE);

if(ret >= 0)
{
printf("%s: %s\n", key, value);
}
else
{
printf("Error finding values\n");
}

printf("ret: %d\n", ret);

return 0;
}


/* if input (fist argument) is not a character string then this program
will Segfault. Do not know how to avoid this :( */
int get_value_using_key(const char* s, const char* k, const int lenk,
char* v, const int lenv)
{
int idx;
char* p;
int bool_small_string = 0;
const char separator = ',';

p = strstr(s, k);

if(NULL == p)
{
printf("No match found\n");
return -1;
}

p = p + lenk + 1; /* +1 for equal character*/

printf("*p = %c\n", *p);

for(idx = 0; idx != lenv; ++idx)
{
if('\0' == *p || separator == *p)
{
bool_small_string = 1;
break;
}

*v++ = *p++;
}

if(bool_small_string)
{
printf("Input size is lesser than recommended. This is fine\n");
}
else if(('\0'== *p || separator == *p) && lenv == idx)
{
printf("Input Size exhausted completely\n");
}
else
{
printf("*p: %c, idx: %d, lenv: %d\n", *p, idx, lenv);
printf("*ERROR - size of input exceeded the allowed limit\n");
return -1;
}

return idx; /* return number of characters read */
}

================= OUTPUT ====================
[[email protected] programs]$ gcc -ansi -pedantic -Wall -Wextra save-values.c
[[email protected] programs]$ ./a.out
input: group=clc,messages=
*p = c
Input size is lesser than recommended. This is fine
group: clc
ret: 3
[[email protected] programs]$
 
Ad

Advertisements

B

Barry Schwarz

Program works fine. I know there are improvements left to be done but
they unidentified by as of now. Help will be appreciated as usual :).
2nd, any strange values that can crash this program and how to avoid them.


/* A program to save input. Input is a character string of key=value
pairs separated by a separator. e.g "name=clc,messages=100".
* We will write a program which will save value when provided with a
belonging key.
*
* VERSION 0.0
*/

#include <stdio.h>
#include <string.h>


enum {
SIZE_VALUE = 20
};


int get_value_using_key(const char* s, const char* k, const int lenk,
char* v, const int lenv);

int main(void)
{
const char* arr = "group=,messages=";
const char* key = "group";

char value[SIZE_VALUE+1] = {0};

Since value is initialized only once (when it is created), you cannot
use it as the output array for multiple calls to your function unless
the values extracted never decrease in length.
int ret;



printf("input: %s\n", arr);
ret = get_value_using_key(arr, key, strlen(key), value, SIZE_VALUE);

if(ret >= 0)
{
printf("%s: %s\n", key, value);
}
else
{
printf("Error finding values\n");
}

printf("ret: %d\n", ret);

return 0;
}


/* if input (fist argument) is not a character string then this program
will Segfault. Do not know how to avoid this :( */

Many of the str** functions suffer from the same "problem". You
simply document the interface for your function that both s and k must
point to strings.
int get_value_using_key(const char* s, const char* k, const int lenk,
char* v, const int lenv)
{
int idx;
char* p;
int bool_small_string = 0;
const char separator = ',';

p = strstr(s, k);

if(NULL == p)
{
printf("No match found\n");
return -1;
}

p = p + lenk + 1; /* +1 for equal character*/

By not including the '=' in the comparison, you have allowed the
function to accept a source like "grouping=" and incorrectly assume
the '=' followed the 'p'.
printf("*p = %c\n", *p);

What makes the first character after the '=' worth printing?
Especially since you print it again later.
for(idx = 0; idx != lenv; ++idx)
{
if('\0' == *p || separator == *p)
{
bool_small_string = 1;
break;
}

*v++ = *p++;
}

if(bool_small_string)
{
printf("Input size is lesser than recommended. This is fine\n");
}
else if(('\0'== *p || separator == *p) && lenv == idx)
{
printf("Input Size exhausted completely\n");

The actual thing exhausted is the array value in main. I have no idea
why this would be called input. It looks more like output.
}
else
{
printf("*p: %c, idx: %d, lenv: %d\n", *p, idx, lenv);
printf("*ERROR - size of input exceeded the allowed limit\n");
return -1;
}

return idx; /* return number of characters read */
}

================= OUTPUT ====================
[[email protected] programs]$ gcc -ansi -pedantic -Wall -Wextra save-values.c
[[email protected] programs]$ ./a.out
input: group=clc,messages=

There is no text "clc" in arr in main. What program did this output
come from? Not from the one you showed above.
*p = c
Input size is lesser than recommended. This is fine
group: clc
ret: 3
[[email protected] programs]$
 
A

arnuld

Since value is initialized only once (when it is created), you cannot
use it as the output array for multiple calls to your function unless
the values extracted never decrease in length.

Thanks. I have taken care of this in the program I am writing (which
sadly is proprietary :( ).


Many of the str** functions suffer from the same "problem". You
simply document the interface for your function that both s and k must
point to strings.

This is where I think C is dangerous.


By not including the '=' in the comparison, you have allowed the
function to accept a source like "grouping=" and incorrectly assume the
'=' followed the 'p'.

corrected.


What makes the first character after the '=' worth printing? Especially
since you print it again later.

Oh.. my bad... its left from those debugging calls to printf().



The actual thing exhausted is the array value in main. I have no idea
why this would be called input. It looks more like output.

That is really funny thing I did.

gcc -ansi -pedantic -Wall -Wextra save-values.c [[email protected] programs]$
./a.out
input: group=clc,messages=

There is no text "clc" in arr in main. What program did this output
come from? Not from the one you showed above.

too many urxvt tabs cause confusion.
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top