Thread: [Dev-C++] Problems with input
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Jan M. <jan...@vo...> - 2007-07-16 12:04:05
|
Hello,
I have got a problem I don't understand very much.
I have in my code:
#include<stdio.h>
int main()
{
char str[10];
getchar ();
gets (str);
printf ("%s\n", str);
return 0;
}
In this case it seems the program is ignoring the
"gets ()" command. After I press some key and >CR>It stops and doesn't wait
for line input. If I do not have there the "getchar () I can input a line.
It runs in Windows console (Command Prompt).
I feel it is some stupid error of me but I don't know where
Thank you
Jan Mura
|
|
From: Adam J. <aj...@i-...> - 2007-07-16 16:18:06
|
>>Hello,
>>I have got a problem I don't understand very much.
>>I have in my code:
>>#include<stdio.h>
>>int main()
>>{
>>char str[10];
>>getchar ();
>>gets (str);
>>printf ("%s\n", str);
>>return 0;
>>}
It would be helpful to all of us if you could explain why you feel it
necessary to use getchar() the gets() the way you do. What are you trying to
accomplish by doing it this way.
getchar() waits for any keypress to continue, and gets will wait until it
encounters the newline or end of file before continuing.
You also have a potential to corrupt memory here. What happens if the person
enters a string longer than 10 Char. You also assume which is not very good
that the system will allocate a char str[10] without checking to see if it
can do it with a malloc first. On memory allocations you need to check
first, and if it fails exit your program gracefully.
>>In this case it seems the program is ignoring the "gets ()" command. After
I press some key and >CR>It stops and doesn't wait for line input. If I do
not have there the "getchar () I >>can input a line.
If you hit any key and the CR then the single key press goes to getchar()
the <CR> goes to the gets() which terminates that call. You should just hit
any key, then type in your string and then hit CR when you are done. The
getchar() does not require you to hit CR in order for it to accept the key
press. This should work.
-Adam Jones
|
|
From: Per W. <pw...@ia...> - 2007-07-17 11:37:00
|
I really don't understand your talk about malloc() and checking for
sucessful allocation here.
If doing
char str = (char*)malloc(10);
then the allocation may fail, the the application should test:
if (str == NULL) fail;
or
if (!str) fail;
However, when declaring:
char str[10];
then the only way the application can fail is if the operating system
can't supply enough stack space. There are no pointer to test. If the
allocation fails (the stack can't fit the variable) then the application
will die.
However, you are correct that gets() should not be used. Or more strongly:
SHOULD NEVER BE USED. If doing C-style input, the function to use is
fgets() since it takes an extra parameter to inform about the size of the
input buffer. gets() is one of the hacker dream functions. If gets() is
used, then the application is compromised.
/pwm
On Mon, 16 Jul 2007, Adam Jones wrote:
> >>Hello,
>
> >>I have got a problem I don't understand very much.
>
> >>I have in my code:
>
> >>#include<stdio.h>
> >>int main()
> >>{
> >>char str[10];
>
> >>getchar ();
> >>gets (str);
> >>printf ("%s\n", str);
> >>return 0;
> >>}
>
> It would be helpful to all of us if you could explain why you feel it
> necessary to use getchar() the gets() the way you do. What are you trying to
> accomplish by doing it this way.
> getchar() waits for any keypress to continue, and gets will wait until it
> encounters the newline or end of file before continuing.
>
> You also have a potential to corrupt memory here. What happens if the person
> enters a string longer than 10 Char. You also assume which is not very good
> that the system will allocate a char str[10] without checking to see if it
> can do it with a malloc first. On memory allocations you need to check
> first, and if it fails exit your program gracefully.
>
> >>In this case it seems the program is ignoring the "gets ()" command. After
> I press some key and >CR>It stops and doesn't wait for line input. If I do
> not have there the "getchar () I >>can input a line.
>
> If you hit any key and the CR then the single key press goes to getchar()
> the <CR> goes to the gets() which terminates that call. You should just hit
> any key, then type in your string and then hit CR when you are done. The
> getchar() does not require you to hit CR in order for it to accept the key
> press. This should work.
>
> -Adam Jones
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Jan M. <jan...@vo...> - 2007-07-17 15:03:32
|
Thanks, the compiler wrote also
the gets () should not be used.
But to be honest I did not know
why.
But the truth is I have seen it cannot be checked by any chance
how many characters will be send to the string.
Jan Mura
----- Original Message -----
From: "Per Westermark" <pw...@ia...>
To: "Adam Jones" <aj...@i-...>
Cc: <dev...@li...>
Sent: Tuesday, July 17, 2007 1:36 PM
Subject: Re: [Dev-C++] Problems with input
> I really don't understand your talk about malloc() and checking for
> sucessful allocation here.
>
> If doing
> char str = (char*)malloc(10);
> then the allocation may fail, the the application should test:
> if (str == NULL) fail;
> or
> if (!str) fail;
>
> However, when declaring:
> char str[10];
> then the only way the application can fail is if the operating system
> can't supply enough stack space. There are no pointer to test. If the
> allocation fails (the stack can't fit the variable) then the application
> will die.
>
>
> However, you are correct that gets() should not be used. Or more strongly:
> SHOULD NEVER BE USED. If doing C-style input, the function to use is
> fgets() since it takes an extra parameter to inform about the size of the
> input buffer. gets() is one of the hacker dream functions. If gets() is
> used, then the application is compromised.
>
> /pwm
>
> On Mon, 16 Jul 2007, Adam Jones wrote:
>
> > >>Hello,
> >
> > >>I have got a problem I don't understand very much.
> >
> > >>I have in my code:
> >
> > >>#include<stdio.h>
> > >>int main()
> > >>{
> > >>char str[10];
> >
> > >>getchar ();
> > >>gets (str);
> > >>printf ("%s\n", str);
> > >>return 0;
> > >>}
> >
> > It would be helpful to all of us if you could explain why you feel it
> > necessary to use getchar() the gets() the way you do. What are you
trying to
> > accomplish by doing it this way.
> > getchar() waits for any keypress to continue, and gets will wait until
it
> > encounters the newline or end of file before continuing.
> >
> > You also have a potential to corrupt memory here. What happens if the
person
> > enters a string longer than 10 Char. You also assume which is not very
good
> > that the system will allocate a char str[10] without checking to see if
it
> > can do it with a malloc first. On memory allocations you need to check
> > first, and if it fails exit your program gracefully.
> >
> > >>In this case it seems the program is ignoring the "gets ()" command.
After
> > I press some key and >CR>It stops and doesn't wait for line input. If I
do
> > not have there the "getchar () I >>can input a line.
> >
> > If you hit any key and the CR then the single key press goes to
getchar()
> > the <CR> goes to the gets() which terminates that call. You should just
hit
> > any key, then type in your string and then hit CR when you are done. The
> > getchar() does not require you to hit CR in order for it to accept the
key
> > press. This should work.
> >
> > -Adam Jones
> >
> >
>
> -------------------------------------------------------------------------
> > This SF.net email is sponsored by DB2 Express
> > Download DB2 Express C - the FREE version of DB2 express and take
> > control of your XML. No limits. Just data. Click to get it now.
> > http://sourceforge.net/powerbar/db2/
> > _______________________________________________
> > Dev-cpp-users mailing list
> > Dev...@li...
> > TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
> >
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
>
> __________ Informace od NOD32 2399 (20070714) __________
>
> Tato zprava byla proverena antivirovym systemem NOD32.
> http://www.nod32.cz
>
>
|
|
From: Adam J. <aj...@i-...> - 2007-07-17 16:11:20
|
>>I really don't understand your talk about malloc() and checking for >>sucessful allocation here. >>If doing >> char str = (char*)malloc(10); >>then the allocation may fail, the the application should test: >> if (str == NULL) fail; >>or >> if (!str) fail; >>However, when declaring: >> char str[10]; >>then the only way the application can fail is if the operating system >>can't supply enough stack space. There are no pointer to test. If the >>allocation fails (the stack can't fit the variable) then the >>application will die. The whole point is to be able to exit the program gracefully and not to hard crash your program. As I stated in my post. Here is what I wrote in the post again: >>You also assume which is > >not very good that the system will allocate a char str[10] without > >checking to see if it can do it with a malloc first. On memory > >allocations you need to check first, and if it fails exit your program gracefully. You assume that letting the system crash is okay. That may be true in the desktop world were you have lots of memory and the person can just reboot their system or kill the program. This is not so true in a mission critical environment were a crash is fatal to a multimillion dollar satellite. In those situations when the malloc fails, You can signal a second system to take over, while controllers on the ground figure out what went wrong with the first system. You just can't let the system crash.... You have to handle it. I admit his example is trivial, but it is a good habit to get into and that was my point..... |
|
From: Jonathan W. <jon...@gm...> - 2007-07-17 09:04:51
|
Hi, Multiple things are happening here: As Adam said, the getchar() will only take one character, the <CR> then gets eaten by the gets(), terminating the string. Also, the gets() will not (and cannot) check the length of the string the user enters against the length of your buffer, therefore mangling your data if the user enters a too-long string. A solution is to use fgets(). See here for an explanation http://www.gidnetwork.com/b-56.html On top of that, you will probably notice with some debugging prints that the letter you type before <CR> is only given to getchar() when you type <CR>. This is because windows (and most OS) only flushes the buffer when lots of data has been sent, or <CR> is pressed. There must be a way to change this behavior, but I'm not familiar with it (try looking for unbuffered stdin) This modification shows what happens with your program: try typing "azerty<CR>" and see what happens #include<stdio.h> int main() { char str[10]; char c; puts("press a key"); c = getchar(); printf("you pressed %c\n",c); puts("enter a string"); gets (str); printf ("you typed %s\n", str); return 0; } However, Adam you are wrong about the allocation of char str[10]: this data will be allocated on the stack, along with other local variables. You can't check whether it failed or not: if there's anough room, ok, if not, the program will have already crashed (stack overflow) before you can do anything (this is why we use malloc() for large amounts of memory, which indeed needs checking) Cheers, Jonathan On 7/16/07, Adam Jones < aj...@i-...> wrote: > > >>Hello, > > >>I have got a problem I don't understand very much. > > >>I have in my code: > > >>#include<stdio.h> > >>int main() > >>{ > >>char str[10]; > > >>getchar (); > >>gets (str); > >>printf ("%s\n", str); > >>return 0; > >>} > > It would be helpful to all of us if you could explain why you feel it > necessary to use getchar() the gets() the way you do. What are you trying > to > accomplish by doing it this way. > getchar() waits for any keypress to continue, and gets will wait until it > encounters the newline or end of file before continuing. > > You also have a potential to corrupt memory here. What happens if the > person > enters a string longer than 10 Char. You also assume which is not very > good > that the system will allocate a char str[10] without checking to see if it > can do it with a malloc first. On memory allocations you need to check > first, and if it fails exit your program gracefully. > > >>In this case it seems the program is ignoring the "gets ()" command. > After > I press some key and >CR>It stops and doesn't wait for line input. If I > do > not have there the "getchar () I >>can input a line. > > If you hit any key and the CR then the single key press goes to getchar() > the <CR> goes to the gets() which terminates that call. You should just > hit > any key, then type in your string and then hit CR when you are done. The > getchar() does not require you to hit CR in order for it to accept the key > press. This should work. > > -Adam Jones > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > -- <Morpheus> linux, c'est une question de VI ou de MORE |
|
From: Jan M. <jan...@vo...> - 2007-07-17 14:01:42
|
Ok, I write a program which behaves according to the value it
get through getchar (kind of a menu).
So it can follow several branches, some of them without
gets().
Of course I know the str array in this case can be a reason of potential
memory leak but I have sent this code only for explainig
what I mean or need.
I have written all of it should be in a program
I am suppose to do and this is just a part of console front-end for
testing purposes and just for me. The production front-ends versions
will be in a Windows API and Symbian API. So I don't care about some
checking in console front-end and
there will be no getchar() or gets() in production versions.
But thank you for advices.
Jan Mura
----- Original Message -----
From: "Adam Jones" <aj...@i-...>
To: <dev...@li...>
Sent: Monday, July 16, 2007 6:17 PM
Subject: Re: [Dev-C++] Problems with input
> >>Hello,
>
> >>I have got a problem I don't understand very much.
>
> >>I have in my code:
>
> >>#include<stdio.h>
> >>int main()
> >>{
> >>char str[10];
>
> >>getchar ();
> >>gets (str);
> >>printf ("%s\n", str);
> >>return 0;
> >>}
>
> It would be helpful to all of us if you could explain why you feel it
> necessary to use getchar() the gets() the way you do. What are you trying
to
> accomplish by doing it this way.
> getchar() waits for any keypress to continue, and gets will wait until it
> encounters the newline or end of file before continuing.
>
> You also have a potential to corrupt memory here. What happens if the
person
> enters a string longer than 10 Char. You also assume which is not very
good
> that the system will allocate a char str[10] without checking to see if it
> can do it with a malloc first. On memory allocations you need to check
> first, and if it fails exit your program gracefully.
>
> >>In this case it seems the program is ignoring the "gets ()" command.
After
> I press some key and >CR>It stops and doesn't wait for line input. If I
do
> not have there the "getchar () I >>can input a line.
>
> If you hit any key and the CR then the single key press goes to getchar()
> the <CR> goes to the gets() which terminates that call. You should just
hit
> any key, then type in your string and then hit CR when you are done. The
> getchar() does not require you to hit CR in order for it to accept the key
> press. This should work.
>
> -Adam Jones
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
>
> __________ Informace od NOD32 2399 (20070714) __________
>
> Tato zprava byla proverena antivirovym systemem NOD32.
> http://www.nod32.cz
>
>
|
|
From: Adam J. <aj...@i-...> - 2007-07-17 18:13:46
|
>>Jonathan Wrote: >>However, Adam you are wrong about the allocation of char str[10]: this data will be allocated on the stack, along with other local variables. You can't check whether it failed or >>not: if there's anough room, ok, if not, the program will have already crashed (stack overflow) before you can do anything (this is why we use malloc() for large amounts of >>memory, which indeed needs checking) When you declare Char str[10], you do create it on the stack. But I was suggesting that he create it on the heap with the Malloc() function. Please reread what I posted, it is listed below again: >>Adam Wrote: >>You also assume which is not very good >>that the system will allocate a char str[10] without checking to see if it >>can do it with a malloc first. On memory allocations you need to check >>first, and if it fails exit your program gracefully. Maybe bad wording, but the fact remains that if you are going to allocate memory, to be safe do it on the heap (using malloc()) instead of the stack. That is what I was suggesting. I hope this clears up any miscommunications on my part..... |
|
From: Jonathan W. <jon...@gm...> - 2007-07-17 22:03:14
|
Ok Adam, I get it now. "...that the system will allocate a char str[10] without checking to see if it can do it with a malloc first." sounded like he should check whether allocating on the stack would work by mallocing it first. Indeed for any large amount of memory, it is safer to allocate on the heap with the malloc family, and then of course, 'large' will depend on the target architecture. Sure thing I wouldn't like satellites hailing down on top of us :) I would usually set 'large' to 100bytes (personal preference), but if this is a recursuve function, even that much should probably be on the heap instead. It seems I'm a bit snappy at the moment, please accept my apologies if I'm being too harsh. Good evening (or whichever it is where you are) Jonathan On 7/17/07, Adam Jones <aj...@i-...> wrote: > > >>Jonathan Wrote: > >>However, Adam you are wrong about the allocation of char str[10]: this > data will be allocated on the stack, along with other local variables. You > can't check whether it failed or >>not: if there's anough room, ok, if > not, > the program will have already crashed (stack overflow) before you can do > anything (this is why we use malloc() for large amounts of >>memory, which > indeed needs checking) > > When you declare Char str[10], you do create it on the stack. But I was > suggesting that he create it on the heap with the Malloc() function. > Please > reread what I posted, it is listed below again: > > >>Adam Wrote: > >>You also assume which is not very good > >>that the system will allocate a char str[10] without checking to see if > it > >>can do it with a malloc first. On memory allocations you need to check > >>first, and if it fails exit your program gracefully. > > Maybe bad wording, but the fact remains that if you are going to allocate > memory, to be safe do it on the heap (using malloc()) instead of the > stack. > That is what I was suggesting. > > I hope this clears up any miscommunications on my part..... > > > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > -- <Morpheus> linux, c'est une question de VI ou de MORE |
|
From: Adam J. <aj...@i-...> - 2007-07-18 01:04:34
|
No problem Jonathan, maybe I should have worded it better. But I do agree with you when you stated: >>I would usually set 'large' to 100bytes (personal preference), but if this is a recursuve function, even that much should probably be on the heap instead. Personally, I do the same. Most modern OSes will allocate more stack space on the fly. As I said the example was a trivial one, and I was just trying to make a point, because I see it all the time. A programmer who thinks they can get away with char[10] may then try to get away with char[64000]. I actually saw that in a program that decodes data from a satellite. As you can imagine the software had problems all the time. What was even worse was the this buffer was called recursively, and it was inside of a thread that did not get terminated properly when the user changed channels. The problems did not show up until the software was running for a bit, because the box it was running on had a large amount of memory...... :) -Adam Jones |