473,386 Members | 1,886 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Question related to string functions

Hi All,

I was going through one piece of code which is written by an
experience programmer and it is working fine.
But I think the use of "strstr" is not proper because it may show
undefined behavior.

char *returnValueFromIniFile(char *iniFilePath,char *keyIntheFile)
{
FILE *FD_IniFileP =NULL;
char key[SIZE_OF_ARRAY]={'0'};
static char value[SIZE_OF_ARRAY]={'\0'};
FD_IniFileP = fopen(iniFilePath,"r");
if( FD_IniFileP != NULL )
{
/* File Open Success*/
while (fscanf(FD_IniFileP,"%s",key)!= EOF)
{
if(strstr(key,keyIntheFile)!=NULL)
{
/*Make sure key contains "="*/
if(strstr(key,"=")!=NULL)
{
/*Sepereate the key and the value */
char *positionOfequal = strstr(key,"="); /* as "="
is not terminated by '\0' it can show undefined behavior ? */

/*increment the positionOfequal to reach the
beganing of the value */
positionOfequal +=1;
assert(strlen(positionOfequal)<SIZE_OF_ARRAY);
strcpy(value,positionOfequal);
break;
}

}/* End of if(strstr(key,keyIntheFile)!=NULL)*/
memset(key,'\0',SIZE_OF_ARRAY);

}/* End of while (fscanf(FD_IniFileP,"%s",key)!= EOF)*/

}/* End of if( FD_IniFileP != NULL )*/
if (FD_IniFileP)
{
fclose(FD_IniFileP);
}

return value;

}

I think the statement "char *positionOfequal = strstr(key,"=");" can
show undefined behavior .
1) Is my understanding correct ?
I have another question
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?
Regards,
Somenath

Sep 10 '07 #1
9 1713
somenath said:
Hi All,

I was going through one piece of code which is written by an
experience programmer and it is working fine.
It fails to protect its key buffer against overruns, so I can't agree
that it's working fine.
But I think the use of "strstr" is not proper because it may show
undefined behavior.
<snip>
if(strstr(key,keyIntheFile)!=NULL)
{
/*Make sure key contains "="*/
if(strstr(key,"=")!=NULL)
{
/*Sepereate the key and the value */
char *positionOfequal = strstr(key,"=");
Calling strstr twice here seems to be a little unnecessary. Still, it's
not actually wrong. Incidentally, strchr would have been adequate.

/* as "="
is not terminated by '\0' it can show undefined behavior ? */
"=" is a string literal, which *IS* terminated by a null character.

<snip>
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?
Yes, you can pass string literals to standard library functions when you
are matching parameters that take const char * (as in your strcpy
example). I can't answer for your Strcat example, since I've never
heard of a Strcat function. If you meant strcat, then yes, that, too,
can legitimately take a string literal as the second argument.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 10 '07 #2
On Sep 10, 8:33 am, Richard Heathfield <r...@see.sig.invalidwrote:
somenath said:
Hi All,
I was going through one piece of code which is written by an
experience programmer and it is working fine.

It fails to protect its key buffer against overruns, so I can't agree
that it's working fine.
Many thanks for the response.

If i have propely understood you are indicating that " while
(fscanf(FD_IniFileP,"%s",key)!= EOF) "
can cause problem . is it so ?
if it is then if I change the code as following will it solve the
problem ?
#define str(x) # x
#define xstr(x) str(x)
char *returnValueFromIniFile(char *iniFilePath,char *keyIntheFile)
{
FILE *FD_IniFileP =NULL;
char key[SIZE_OF_ARRAY+1]={'0'};
static char value[1]={'\0'};
FD_IniFileP = fopen(iniFilePath,"r");
if( FD_IniFileP != NULL )
{
/* File Open Success*/
//cout<<"\n Opening of INI file Succeeded \n "<<endl;
while (fscanf(FD_IniFileP,"%" xstr(SIZE_OF_ARRAY) "[^
\n]" ,key)!= EOF)
{
>
But I think the use of "strstr" is not proper because it may show
undefined behavior.

<snip>
if(strstr(key,keyIntheFile)!=NULL)
{
/*Make sure key contains "="*/
if(strstr(key,"=")!=NULL)
{
/*Sepereate the key and the value */
char *positionOfequal = strstr(key,"=");

Calling strstr twice here seems to be a little unnecessary. Still, it's
not actually wrong. Incidentally, strchr would have been adequate.

/* as "="
is not terminated by '\0' it can show undefined behavior ? */

"=" is a string literal, which *IS* terminated by a null character.

<snip>
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?

Yes, you can pass string literals to standard library functions when you
are matching parameters that take const char * (as in your strcpy
example). I can't answer for your Strcat example, since I've never
heard of a Strcat function. If you meant strcat,
Sorry it is my typing mistake. It would be strcat.
then yes, that, too,
can legitimately take a string literal as the second argument.


Sep 10 '07 #3
On Sep 10, 8:33 am, Richard Heathfield <r...@see.sig.invalidwrote:
somenath said:
Hi All,
I was going through one piece of code which is written by an
experience programmer and it is working fine.

It fails to protect its key buffer against overruns, so I can't agree
that it's working fine.
But I think the use of "strstr" is not proper because it may show
undefined behavior.

<snip>
if(strstr(key,keyIntheFile)!=NULL)
{
/*Make sure key contains "="*/
if(strstr(key,"=")!=NULL)
{
/*Sepereate the key and the value */
char *positionOfequal = strstr(key,"=");

Calling strstr twice here seems to be a little unnecessary. Still, it's
not actually wrong. Incidentally, strchr would have been adequate.

/* as "="
is not terminated by '\0' it can show undefined behavior ? */

"=" is a string literal, which *IS* terminated by a null character.

<snip>
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?

Yes, you can pass string literals to standard library functions when you
are matching parameters that take const char * (as in your strcpy
example). I can't answer for your Strcat example, since I've never
heard of a Strcat function. If you meant strcat, then yes, that, too,
can legitimately take a string literal as the second argument.
I have one doubt here.
Suppose
#define TEMP_STR "xyz"
can i use string related function such as strcpy(dest,TEMP_STR); ?

Sep 10 '07 #4
somenath said:
On Sep 10, 8:33 am, Richard Heathfield <r...@see.sig.invalidwrote:
<snip>
>Yes, you can pass string literals to standard library functions when
you are matching parameters that take const char * (as in your strcpy
example). [...]
I have one doubt here.
Suppose
#define TEMP_STR "xyz"
can i use string related function such as strcpy(dest,TEMP_STR); ?
Yes, because it's just a different way of writing strcpy(dest,"xyz");

But TEMP_STR is a bad name for a string literal. String literals exist
for the entire lifetime of the program, so they are hardly temporary!

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 10 '07 #5
somenath <so*********@gmail.comwrites:
I was going through one piece of code which is written by an
experience programmer and it is working fine.
But I think the use of "strstr" is not proper because it may show
undefined behavior.
[...]
/*Sepereate the key and the value */
char *positionOfequal = strstr(key,"="); /* as "="
is not terminated by '\0' it can show undefined behavior ? */
[...]
I think the statement "char *positionOfequal = strstr(key,"=");" can
show undefined behavior .
1) Is my understanding correct ?
I have another question
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?
A string literal is (almost) always implicitly terminated by a '\0'
character. The literal "=" specifies the two-character sequence
'=', '\0'.

(The only exception is when a string literal is used to initialize an
array whose size is specified as exactly the length of the array, such
as
char s[3] = "abc";
but this is a very unusual case, and should be avoided; instead, you
can use
char s[] = "abc";
to get a properly zero-terminated string.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 10 '07 #6
Keith Thompson said:
somenath <so*********@gmail.comwrites:
>I was going through one piece of code which is written by an
experience programmer and it is working fine.
But I think the use of "strstr" is not proper because it may show
undefined behavior.
[...]
> /*Sepereate the key and the value */
char *positionOfequal = strstr(key,"="); /* as
"="
is not terminated by '\0' it can show undefined behavior ? */
[...]
>I think the statement "char *positionOfequal = strstr(key,"=");" can
show undefined behavior .
1) Is my understanding correct ?
I have another question
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?

A string literal is (almost) always implicitly terminated by a '\0'
character. The literal "=" specifies the two-character sequence
'=', '\0'.

(The only exception is when a string literal is used to initialize an
array whose size is specified as exactly the length of the array, such
as
char s[3] = "abc";
What makes you think this is an exception?

The Standard says:

"A character string literal has static storage duration and type "array
of char," and is initialized with the given characters. A wide string
literal has static storage duration and type "array of wchar_t," and is
initialized with the wide characters corresponding to the given
multibyte characters. Character string literals that are adjacent
tokens are concatenated into a single character string literal. A null
character is then appended."

No exceptions.

I know what you're thinking of, but that's a special case of
initialisation, not a special case of string literals.

but this is a very unusual case, and should be avoided;
....by newbies, at any rate. There are (rare) times when it's Exactly
What's Needed.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 10 '07 #7
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
[...]
>A string literal is (almost) always implicitly terminated by a '\0'
character. The literal "=" specifies the two-character sequence
'=', '\0'.

(The only exception is when a string literal is used to initialize an
array whose size is specified as exactly the length of the array, such
as
char s[3] = "abc";

What makes you think this is an exception?

The Standard says:

"A character string literal has static storage duration and type "array
of char," and is initialized with the given characters. A wide string
literal has static storage duration and type "array of wchar_t," and is
initialized with the wide characters corresponding to the given
multibyte characters. Character string literals that are adjacent
tokens are concatenated into a single character string literal. A null
character is then appended."

No exceptions.

I know what you're thinking of, but that's a special case of
initialisation, not a special case of string literals.
What are you, some kind of pedant?

8-)}

Yeah, you're right. C99 6.7.8p14 says:

An array of character type may be initialized by a character
string literal, optionally enclosed in braces. Successive
characters of the character string literal (including the
terminating null character if there is room or if the array is of
unknown size) initialize the elements of the array.
>but this is a very unusual case, and should be avoided;

...by newbies, at any rate. There are (rare) times when it's Exactly
What's Needed.
Hmm. I meant to qualify that somehow, and I thought I had.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 10 '07 #8
somenath wrote:
On Sep 10, 8:33 am, Richard Heathfield <r...@see.sig.invalidwrote:
>somenath said:
Hi All,
I was going through one piece of code which is written by an
experience programmer and it is working fine.

It fails to protect its key buffer against overruns, so I can't agree
that it's working fine.

Many thanks for the response.

If i have propely understood you are indicating that " while
(fscanf(FD_IniFileP,"%s",key)!= EOF) "
can cause problem . is it so ?
if it is then if I change the code as following will it solve the
problem ?
#define str(x) # x
#define xstr(x) str(x)
char *returnValueFromIniFile(char *iniFilePath,char *keyIntheFile)
{
FILE *FD_IniFileP =NULL;
char key[SIZE_OF_ARRAY+1]={'0'};
static char value[1]={'\0'};
FD_IniFileP = fopen(iniFilePath,"r");
if( FD_IniFileP != NULL )
{
/* File Open Success*/
//cout<<"\n Opening of INI file Succeeded \n "<<endl;
while (fscanf(FD_IniFileP,"%" xstr(SIZE_OF_ARRAY) "[^
\n]" ,key)!= EOF)
{
Yes, that will properly protect you from a buffer overrun of the key
array.
But your change also changes the semantics of the program.
The original line:
*while (fscanf(FD_IniFileP,"%s",key)!= EOF)
would stop reading on the first whitespace character, but your rewrite
only stops at the end of a line.
To preserve the original semantics, you should use
while (fscanf(FD_IniFileP,"%" xstr(SIZE_OF_ARRAY) "s" ,key)!= EOF)

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
Sep 10 '07 #9

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Richard Heathfield <rj*@see.sig.invalidwrites:
>I know what you're thinking of, but that's a special case of
initialisation, [ unterminated char arrays] not a special case of
string literals.

What are you, some kind of pedant?
If we can't be literal about literals, where is it appropriate?

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Sep 10 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Exits Funnel | last post by:
Hello, I've two quick questions. Suppose I've got the following: char* cptr = "This is potentially, a really, really long string"; I need to determine if the string contains "PULP FICTION"...
14
by: Flzw | last post by:
Well I have a map like this : std::map <string, CObject> ObjectList; I have a function like this : CObject* NewObject( char* Name, CArg* Arg) { std::string key = Name; ObjectList =...
11
by: xuatla | last post by:
Hi, I want to compare two strings regardless of the lowercase or uppercase. For example, "txt" same as "TXT", "Txt", ... I know that there's stricmp in some c++ that can perform a lowercase...
6
by: rodchar | last post by:
Hey all, I'm trying to understand Master/Detail concepts in VB.NET. If I do a data adapter fill for both customer and orders from Northwind where should that dataset live? What client is...
5
by: RKS | last post by:
I am new to Com programming using C++. Can pointers be passed through interface functions. I would like to pass multi dimensional arrays to functions defined in the com interface. Any help is...
2
by: =?iso-8859-1?q?Erik_Wikstr=F6m?= | last post by:
I'm working on a project where I need a couple of classes that purely conceptually are related to each other such that I could create a base-class and have a is-a relation between each of the...
6
by: JonathanOrlev | last post by:
Hello everyone, I have a newbe question: In Access (2003) VBA, what is the difference between a Module and a Class Module in the VBA development environment? If I remember correctly, new...
0
by: | last post by:
I have a question about spawning and displaying subordinate list controls within a list control. I'm also interested in feedback about the design of my search application. Lots of code is at the...
15
by: nikki_herring | last post by:
I am using setTimeout( ) to continuously call a function that randomly rotates/displays 2 images on a page. The part I need help with is the second image should rotate 3 seconds after the first...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.