|
From: Christian W. <Chr...@vo...> - 2001-10-18 12:38:34
|
Hi list,
I try to write a little Dos-tool.
If I want to get the parameters and the user has no parameters specified I
get an exception.
I think the error comes if i call strlen() with an empty string...
How can i handle this error, has anyone an idea ????
----------------Schnipp---------------------
//Get commandline
strcpy(szDatei, argv[1]);
for (nCount = 2; argc > nCount; ++nCount)
{
strcat(szDatei, " \0");
strcat(szDatei, argv[nCount]);
};
//Check Commandline
if (strlen(szDatei) <= 5)
{
printf("Wrong parameter !");
};
-------------------Schnapp------------------
Thanx for help
Chris
Diese Mail wurde auf Viren überprüft.
This mail was checked for virusses.
|
|
From: Jason H. <jas...@bt...> - 2001-10-18 14:04:36
|
You are trying to access an argv member that doesn't exist, in the strcpy()
function. The array starts at zero so with an empty command line only
argv[0] will be valid and it will contain the name of the executable.
Jason.
----- Original Message -----
From: "Christian Wallukat" <Chr...@vo...>
To: "CPP-Maillinglist (E-Mail)" <dev...@li...>
Sent: Thursday, October 18, 2001 1:40 PM
Subject: [Dev-C++] Errorhandling
> Hi list,
>
>
> I try to write a little Dos-tool.
> If I want to get the parameters and the user has no parameters specified I
> get an exception.
>
> I think the error comes if i call strlen() with an empty string...
>
> How can i handle this error, has anyone an idea ????
>
>
>
> ----------------Schnipp---------------------
> //Get commandline
> strcpy(szDatei, argv[1]); // ** try argv[0]**
> for (nCount = 2; argc > nCount; ++nCount)
> {
> strcat(szDatei, " \0");
> strcat(szDatei, argv[nCount]);
> };
>
> //Check Commandline
> if (strlen(szDatei) <= 5)
> {
> printf("Wrong parameter !");
> };
> -------------------Schnapp------------------
>
>
> Thanx for help
>
>
> Chris
>
> Diese Mail wurde auf Viren überprüft.
> This mail was checked for virusses.
>
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
|
|
From: Ioannis V. <no...@ya...> - 2001-10-18 20:32:14
|
> -----Original Message-----
> From: dev...@li...=20
> [mailto:dev...@li...] On Behalf=20
> Of Christian Wallukat
> Sent: Thursday, October 18, 2001 2:40 PM
> To: CPP-Maillinglist (E-Mail)
> Subject: [Dev-C++] Errorhandling
>=20
>=20
> Hi list,
>=20
>=20
> I try to write a little Dos-tool.
> If I want to get the parameters and the user has no=20
> parameters specified I get an exception.
>=20
> I think the error comes if i call strlen() with an empty string...
>=20
> How can i handle this error, has anyone an idea ????
>=20
>=20
>=20
> ----------------Schnipp---------------------
> //Get commandline
> strcpy(szDatei, argv[1]);
> for (nCount =3D 2; argc > nCount; ++nCount)
> {
> strcat(szDatei, " \0");
> strcat(szDatei, argv[nCount]);
> };
>=20
> //Check Commandline
> if (strlen(szDatei) <=3D 5)=20
> {
> printf("Wrong parameter !");
> };
> -------------------Schnapp------------------
>=20
>=20
> Thanx for help
>=20
>=20
> Chris
The errors may be many. For example szDatei may not have the necessary
size to hold all these strings... Except of that, strcat(szDatei, "
\0"); is a mistake. So wwe do not know if you get an exception, the most
possible is that you get memory access error.
For more bullet proof code use C++ higher level constructs like string.
E.g.
#include <iostream>
#include <string>
...
//somewhere in a function
using namespace std;
...
if(argc>1)
string szDatei=3Dargv[1];
for (int nCount =3D 2; nCount<argc; ++nCount)
szDatei+=3D argv[nCount]);
//Check Commandline
if (szDatei.size() <=3D 5)=20
cout<<"Wrong parameter !";
This is the equivallent higher level C++ code with your mistakes
corrected (the first if statement, and int nCount in the for loop).
Ioannis
* Ioannis Vranos
* Programming pages: http://www.noicys.f2s.com
* Alternative URL: http://run.to/noicys
|
|
From: Jason H. <jas...@bt...> - 2001-10-18 22:12:55
|
I think the strcat(szDatei, " \0") was to insert a space between the comand
line arguments when concatenating them. Any string literal will be
automatically NULL terminated anyway, but putting in the extra NULL wouldn't
cause any harm as strcat would just ignore it. A C++ string would be better,
but perhaps he was intentionally writing in pure C?
I've been haveing a look at the C99 standard of late and some of the
developments in there would make it useful to use C instead of C++. C is no
longer a subset of C++, although maybe in future they will extend C++ to
include at least some of the inovations? Of course I don't think that the
compiler used in Dev-C++ supports it yet.
Jason.
----- Original Message -----
From: "Ioannis Vranos" <no...@ya...>
To: "Dev-C++" <dev...@li...>
Sent: Thursday, October 18, 2001 10:33 PM
Subject: RE: [Dev-C++] Errorhandling
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...] On Behalf
> Of Christian Wallukat
> Sent: Thursday, October 18, 2001 2:40 PM
> To: CPP-Maillinglist (E-Mail)
> Subject: [Dev-C++] Errorhandling
>
>
> Hi list,
>
>
> I try to write a little Dos-tool.
> If I want to get the parameters and the user has no
> parameters specified I get an exception.
>
> I think the error comes if i call strlen() with an empty string...
>
> How can i handle this error, has anyone an idea ????
>
>
>
> ----------------Schnipp---------------------
> //Get commandline
> strcpy(szDatei, argv[1]); // *** access violation
// *** argv[1] doesn't exist with no commands passed!
> for (nCount = 2; argc > nCount; ++nCount)
> {
> strcat(szDatei, " ");
> strcat(szDatei, argv[nCount]);
> };
>
> //Check Commandline
> if (strlen(szDatei) <= 5)
> {
> printf("Wrong parameter !");
> };
> -------------------Schnapp------------------
>
>
> Thanx for help
>
>
> Chris
The errors may be many. For example szDatei may not have the necessary
size to hold all these strings... Except of that, strcat(szDatei, "
\0"); is a mistake. So wwe do not know if you get an exception, the most
possible is that you get memory access error.
For more bullet proof code use C++ higher level constructs like string.
E.g.
#include <iostream>
#include <string>
...
//somewhere in a function
using namespace std;
...
if(argc>1)
string szDatei=argv[1];
for (int nCount = 2; nCount<argc; ++nCount)
szDatei+= " " + argv[nCount]); // ***added a space
//Check Commandline
if (szDatei.size() <= 5)
cout<<"Wrong parameter !";
This is the equivallent higher level C++ code with your mistakes
corrected (the first if statement, and int nCount in the for loop).
Ioannis
* Ioannis Vranos
* Programming pages: http://www.noicys.f2s.com
* Alternative URL: http://run.to/noicys
_______________________________________________
Dev-cpp-users mailing list
Dev...@li...
https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
|
|
From: Ioannis V. <no...@ya...> - 2001-10-19 08:24:13
|
> -----Original Message----- > From: dev...@li...=20 > [mailto:dev...@li...] On Behalf=20 > Of Jason Hardman > Sent: Friday, October 19, 2001 12:13 AM > To: Dev-C++ > Subject: Re: [Dev-C++] Errorhandling >=20 >=20 > I think the strcat(szDatei, " \0") was to insert a space=20 > between the comand line arguments when concatenating them.=20 The proper in this case would be: strcat(sdDatei, " "); > Any string literal will be automatically NULL terminated=20 > anyway, but putting in the extra NULL wouldn't cause any harm=20 > as strcat would just ignore it. A C++ string would be better, We do not know if it would ignore it, it could end up in a concatenated string having a double '\0', and in the next call of strcat() it could end up in something like that: [stringonestringtwo\0stringthree...\0] That is we do not know how a strcat() implementation works (perhaps from the end towards the beginning) and it could replace the last '\0' only. In any case that '\0' is not needed. =20 > but perhaps he was intentionally writing in pure C? Perhaps, but he spoke for exceptions so i assumed knowledge of C++ so i assumed C++. :) > I've been haveing a look at the C99 standard of late and some=20 > of the developments in there would make it useful to use C=20 > instead of C++. C is no longer a subset of C++, although=20 C99 is not a subset of C++ but i can;t find a reason why using C99 would be more useful than C++ (i think exactly the opposite). > maybe in future they will extend C++ to include at least some=20 > of the inovations? Of course I don't think that the compiler=20 Only very few. Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.f2s.com * Alternative URL: http://run.to/noicys |
|
From: Jason H. <jas...@bt...> - 2001-10-19 14:42:08
|
I can say for certain that strcat() won't ever include any extra '\0' into a
string. If it did it would be due to a bug in the routine. The function is
passed a pointer to the beginning of two strings, so the only way it could
start at the end of a string would be to look for it. The only way it can
determine the end is to find the null terminator, which will be the first 0
it finds. It won't look beyond that zero, so won't see any other text or
zero's that may exist. Once it has found the end of the first string it will
add on the characters from the second, overwring the null terminator in the
first and any other stuff that is there. It will go on till it finds the
NULL on the second string and will be sure to add a NULL onto the
concatenated string. Here is a short function that probably does the same as
the standard one.
MyStrCat(char *str1, const char *str2)
{
while(*str1) ++str1; // find end of first string
// out now points to the null of out
while(*str2)
*str1++ = *str2++; // copy second string
// to end of first.
*str1 = 0; // null terminate
}
Note that if you pass two pointers to the same string you will get an
infinate loop.
Regards Jason.
PS: guess I've gone OTT again.... oops!
----- Original Message -----
From: "Ioannis Vranos" <no...@ya...>
To: "Dev-C++" <dev...@li...>
Sent: Friday, October 19, 2001 10:25 AM
Subject: RE: [Dev-C++] Errorhandling
> Any string literal will be automatically NULL terminated
> anyway, but putting in the extra NULL wouldn't cause any harm
> as strcat would just ignore it. A C++ string would be better,
We do not know if it would ignore it, it could end up in a concatenated
string having a double '\0', and in the next call of strcat() it could
end up in something like that:
[stringonestringtwo\0stringthree...\0]
That is we do not know how a strcat() implementation works (perhaps from
the end towards the beginning) and it could replace the last '\0' only.
In any case that '\0' is not needed.
|
|
From: Ioannis V. <no...@ya...> - 2001-10-19 15:20:38
|
> -----Original Message-----
> From: dev...@li...=20
> [mailto:dev...@li...] On Behalf=20
> Of Jason Hardman
> Sent: Friday, October 19, 2001 4:40 PM
> To: Dev-C++
> Subject: Re: [Dev-C++] Errorhandling
>=20
>=20
> I can say for certain that strcat() won't ever include any=20
> extra '\0' into a string. If it did it would be due to a bug=20
> in the routine. The function is passed a pointer to the=20
> beginning of two strings, so the only way it could start at=20
> the end of a string would be to look for it. The only way it=20
You can't know it. strcat() can be written even in assembly and only the
author's mind knows how it works. Simply C and C++ guarantee that you
can write these stuff with the language itself. :) When you use strcat()
don't necessarily imagine a for loop looking for the first occurence of
'\0'. This would be very slow for very large strings. A method i am now
thinking is memcpy() some large blocks and search for '\0' in each of
these blocks, but as i said a compiler makes the memory management
itself and compiler stuff may include things more close to the machine
than these we write outside of the compiler.
> can determine the end is to find the null terminator, which=20
> will be the first 0 it finds. It won't look beyond that zero,=20
> so won't see any other text or zero's that may exist. Once it=20
> has found the end of the first string it will add on the=20
> characters from the second, overwring the null terminator in=20
> the first and any other stuff that is there. It will go on=20
> till it finds the NULL on the second string and will be sure=20
> to add a NULL onto the concatenated string. Here is a short=20
> function that probably does the same as the standard one.
>=20
> MyStrCat(char *str1, const char *str2)
> {
> while(*str1) ++str1; // find end of first string
> // out now points to the null of out
> while(*str2)
> *str1++ =3D *str2++; // copy second string
> // to end of first.
> *str1 =3D 0; // null terminate
> }
That's nice for a first approach but imagine that you had a string with
5 thousand characters... As i said you can write even faster function
using C or C++ but it can be written in assembly too in something like
that:
inline void MyStrCat(char *str1, const char *str2)
{
asm("Bizarre code here");
....
}
It can be even "worse". :) Stroustrup writes in Special Edition that
they may be no header files at all and #include statements can work as
on/off switches!
E.g..
#include <cstdio> // switch that makes the cstdio library functions
accessible.
That means they are all automatically accessible and you define
accessibility using #include statements. :)
>=20
> Note that if you pass two pointers to the same string you=20
> will get an infinate loop.
>=20
> Regards Jason.
>=20
> PS: guess I've gone OTT again.... oops!
What's OTT? :)
Ioannis
* Ioannis Vranos
* Programming pages: http://www.noicys.f2s.com
* Alternative URL: http://run.to/noicys
|
|
From: Jason H. <jas...@bt...> - 2001-10-20 02:16:30
|
As defined in C/C++ Programmers Reference: strcat ------ #include <string.h> char *strcat(char *str1, const char *str2); The strcat() function concatenates a copy of str2 to str1 and terminates str1 with a null. The null terminator originally ending str1 is overwritten by the first character of str2. The string str2 is untouched by the operation. If the arrays overlap, the behavior of strcat() is undefined. In C99, str1 and str2 are qualified by restrict. The strcat() function returns str1. Remember, no bounds checking takes place, so it is the programmer's responsibility to ensure that str1 is large enough to hold both its original contents and also those of str2. ------------------------ The function strcat() is defined in the C, and therefore the C++, standard. It must follow a consistent behaviour. It is feasible that it could have been written in assembler, but it will still have the same basic behaviour. I know it would be slow in large strings, but there isn't really any faster and reliable way to search for the null. Skipping characters opens up the possibility of missing the proper null, and accessing characters after it which will be undefined. In strcat you might not overrun the array containing the string that way, but in a similar function such as strlen you probably would, and that would be an access violation. Without more information about the string being passed then you are pretty much limited to going throught the string from start to finish. Generally if a programmer was dealing with very large string then it would be wise for him/her to find a better way of dealing with them (such as tracking the length), or to just accept the performance hit. Whether the include is an on/off switch or a header won't change the way the function works, just how the compiler adds it to the exe. Regards, Jason. PS: Yet again I've probably gone OTT (Over The Top). LOL! It looks like I've written an essay on a standard function. PPS: Why is it us to always seem to be arguing over silly little things like this? |
|
From: Ioannis V. <no...@ya...> - 2001-10-20 10:28:40
|
At first, we do not argue we discuss. It is fun to discuss for C and C++. :) Anyway, the standard doesn't say that it looks character after character (compiler has its own internal memory management and it may mark large blocks of memory with length numbers and stuff: read the 8th chapter of K&R 2 and in particular 8.7 where it has an implementation of malloc) but you are probably right, it probably behaves as if it looks from character to character. But the main point here is that strcat(buffer, "a string\0"); is worthless and is looking for trouble. I am 100% sure that in certain occasions it means trouble. E.g. like you use sizeof on a char array to determine the length of the string and not strlen() as i saw in some email in this list. In summary using "string\0" shows lack of knowledge at least. Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.f2s.com * Alternative URL: http://run.to/noicys > -----Original Message----- > From: dev...@li...=20 > [mailto:dev...@li...] On Behalf=20 > Of Jason Hardman > Sent: Saturday, October 20, 2001 1:38 AM > To: Dev-C++ > Subject: Re: [Dev-C++] Errorhandling >=20 >=20 > As defined in C/C++ Programmers Reference: >=20 > strcat > ------ > #include <string.h> > char *strcat(char *str1, const char *str2); >=20 > The strcat() function concatenates a copy of str2 to str1 and=20 > terminates str1 with a null. The null terminator originally=20 > ending str1 is overwritten by the first character of str2.=20 > The string str2 is untouched by the operation. If the arrays=20 > overlap, the behavior of strcat() is undefined. >=20 > In C99, str1 and str2 are qualified by restrict. >=20 > The strcat() function returns str1. >=20 > Remember, no bounds checking takes place, so it is the=20 > programmer's responsibility to ensure that str1 is large=20 > enough to hold both its original contents and also those of str2. > ------------------------ >=20 > The function strcat() is defined in the C, and therefore the=20 > C++, standard. It must follow a consistent behaviour. It is=20 > feasible that it could have been written in assembler, but it=20 > will still have the same basic behaviour. I know it would be=20 > slow in large strings, but there isn't really any faster and=20 > reliable way to search for the null. Skipping characters=20 > opens up the possibility of missing the proper null, and=20 > accessing characters after it which will be undefined. In=20 > strcat you might not overrun the array containing the string=20 > that way, but in a similar function such as strlen you=20 > probably would, and that would be an access violation. >=20 > Without more information about the string being passed then=20 > you are pretty much limited to going throught the string from=20 > start to finish. Generally if a programmer was dealing with=20 > very large string then it would be wise for him/her to find a=20 > better way of dealing with them (such as tracking the=20 > length), or to just accept the performance hit. >=20 > Whether the include is an on/off switch or a header won't=20 > change the way the function works, just how the compiler adds=20 > it to the exe. >=20 > Regards, Jason. >=20 > PS: Yet again I've probably gone OTT (Over The Top). LOL! It=20 > looks like I've written an essay on a standard function. >=20 > PPS: Why is it us to always seem to be arguing over silly=20 > little things like this? >=20 >=20 > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users >=20 |
|
From: Jason H. <jas...@bt...> - 2001-10-20 12:55:19
|
OK then that's agreed. And I admit I did once use sizeof to determine the length of a string array, but only cos it was a string of constant length, although I can't remember if I created it as a constant string. I shall never transgress again. ;-D I wonder if the original poster has been paying any attention to us two. I hope at least he has learnt that you don't need to null terminate a string literal by hand. Jason. ----- Original Message ----- From: "Ioannis Vranos" <no...@ya...> To: "Dev-C++" <dev...@li...> Sent: Saturday, October 20, 2001 12:30 PM Subject: RE: [Dev-C++] Errorhandling At first, we do not argue we discuss. It is fun to discuss for C and C++. :) Anyway, the standard doesn't say that it looks character after character (compiler has its own internal memory management and it may mark large blocks of memory with length numbers and stuff: read the 8th chapter of K&R 2 and in particular 8.7 where it has an implementation of malloc) but you are probably right, it probably behaves as if it looks from character to character. But the main point here is that strcat(buffer, "a string\0"); is worthless and is looking for trouble. I am 100% sure that in certain occasions it means trouble. E.g. like you use sizeof on a char array to determine the length of the string and not strlen() as i saw in some email in this list. In summary using "string\0" shows lack of knowledge at least. Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.f2s.com * Alternative URL: http://run.to/noicys > -----Original Message----- > From: dev...@li... > [mailto:dev...@li...] On Behalf > Of Jason Hardman > Sent: Saturday, October 20, 2001 1:38 AM > To: Dev-C++ > Subject: Re: [Dev-C++] Errorhandling > > > As defined in C/C++ Programmers Reference: > > strcat > ------ > #include <string.h> > char *strcat(char *str1, const char *str2); > > The strcat() function concatenates a copy of str2 to str1 and > terminates str1 with a null. The null terminator originally > ending str1 is overwritten by the first character of str2. > The string str2 is untouched by the operation. If the arrays > overlap, the behavior of strcat() is undefined. > > In C99, str1 and str2 are qualified by restrict. > > The strcat() function returns str1. > > Remember, no bounds checking takes place, so it is the > programmer's responsibility to ensure that str1 is large > enough to hold both its original contents and also those of str2. > ------------------------ > > The function strcat() is defined in the C, and therefore the > C++, standard. It must follow a consistent behaviour. It is > feasible that it could have been written in assembler, but it > will still have the same basic behaviour. I know it would be > slow in large strings, but there isn't really any faster and > reliable way to search for the null. Skipping characters > opens up the possibility of missing the proper null, and > accessing characters after it which will be undefined. In > strcat you might not overrun the array containing the string > that way, but in a similar function such as strlen you > probably would, and that would be an access violation. > > Without more information about the string being passed then > you are pretty much limited to going throught the string from > start to finish. Generally if a programmer was dealing with > very large string then it would be wise for him/her to find a > better way of dealing with them (such as tracking the > length), or to just accept the performance hit. > > Whether the include is an on/off switch or a header won't > change the way the function works, just how the compiler adds > it to the exe. > > Regards, Jason. > > PS: Yet again I've probably gone OTT (Over The Top). LOL! It > looks like I've written an essay on a standard function. > > PPS: Why is it us to always seem to be arguing over silly > little things like this? > > > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > _______________________________________________ Dev-cpp-users mailing list Dev...@li... https://lists.sourceforge.net/lists/listinfo/dev-cpp-users |
|
From: Ioannis V. <no...@ya...> - 2001-10-20 21:52:48
|
My last note on the matter is i want to reinforce that, yes you are *right*, strcat() places the new string at the first occurence of '\0' of its first argument (=3Dit behaves as if it searches character by character from the beginning for '\0') because i used the term "probably" in my previous email regarding the matter. Also as i said "string\0" is looking for trouble in our code.=20 That doesn't mean that strcat() searches character by character for 0 but it *behaves* as if it does that. The same way that pointers *behave* as if they store a memory address, string literals *behave* as null terminated const char arrays, e.t.c.. This is important for all to keep in mind. :) This behavior is required by the standard, but it doesn't mean things happen this way. But it is safe to think of them as working this way. Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.f2s.com * Alternative URL: http://run.to/noicys > -----Original Message----- > From: dev...@li... > [mailto:dev...@li...] On Behalf=20 > Of Jason Hardman > Sent: Saturday, October 20, 2001 1:38 AM > To: Dev-C++ > Subject: Re: [Dev-C++] Errorhandling >=20 >=20 > As defined in C/C++ Programmers Reference: >=20 > strcat > ------ > #include <string.h> > char *strcat(char *str1, const char *str2); >=20 > The strcat() function concatenates a copy of str2 to str1 and > terminates str1 with a null. The null terminator originally=20 > ending str1 is overwritten by the first character of str2.=20 > The string str2 is untouched by the operation. If the arrays=20 > overlap, the behavior of strcat() is undefined. >=20 > In C99, str1 and str2 are qualified by restrict. >=20 > The strcat() function returns str1. >=20 > Remember, no bounds checking takes place, so it is the > programmer's responsibility to ensure that str1 is large=20 > enough to hold both its original contents and also those of str2. > ------------------------ >=20 > The function strcat() is defined in the C, and therefore the > C++, standard. It must follow a consistent behaviour. It is > feasible that it could have been written in assembler, but it > will still have the same basic behaviour. I know it would be=20 > slow in large strings, but there isn't really any faster and=20 > reliable way to search for the null. Skipping characters=20 > opens up the possibility of missing the proper null, and=20 > accessing characters after it which will be undefined. In=20 > strcat you might not overrun the array containing the string=20 > that way, but in a similar function such as strlen you=20 > probably would, and that would be an access violation. >=20 > Without more information about the string being passed then > you are pretty much limited to going throught the string from=20 > start to finish. Generally if a programmer was dealing with=20 > very large string then it would be wise for him/her to find a=20 > better way of dealing with them (such as tracking the=20 > length), or to just accept the performance hit. >=20 > Whether the include is an on/off switch or a header won't > change the way the function works, just how the compiler adds=20 > it to the exe. >=20 > Regards, Jason. >=20 > PS: Yet again I've probably gone OTT (Over The Top). LOL! It > looks like I've written an essay on a standard function. >=20 > PPS: Why is it us to always seem to be arguing over silly > little things like this? >=20 >=20 > _______________________________________________ > Dev-cpp-users mailing list Dev...@li... > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users >=20 |