Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #140136 > unrolled thread
| Started by | DFS <nospam@dfs.com> |
|---|---|
| First post | 2019-01-23 21:00 -0500 |
| Last post | 2019-01-24 03:53 -0800 |
| Articles | 20 on this page of 54 — 19 participants |
Back to article view | Back to comp.lang.c
Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-23 21:00 -0500
Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-23 19:14 -0700
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-23 23:41 -0500
Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-23 22:40 -0700
Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 10:44 +0000
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 11:20 -0500
Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 16:47 +0000
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 13:51 -0500
Re: Function to trim trailing spaces Manfred <noname@invalid.add> - 2019-01-24 17:49 +0100
Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 08:52 -0800
Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 17:40 +0000
Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 12:08 -0800
Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 14:47 -0700
Re: Function to trim trailing spaces scott@slp53.sl.home (Scott Lurndal) - 2019-01-25 14:40 +0000
Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 14:44 -0700
Re: Function to trim trailing spaces Barry Schwarz <schwarzb@dqel.com> - 2019-01-23 23:39 -0800
Re: Function to trim trailing spaces Rosario19 <Ros@invalid.invalid> - 2019-01-24 10:49 +0100
Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 01:55 -0800
Re: Function to trim trailing spaces "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-24 12:58 +0100
Re: Function to trim trailing spaces Nathan Wagner <nw@hydaspes.if.org> - 2019-01-24 03:01 +0000
Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-23 18:46 -0800
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-23 23:38 -0500
Re: Function to trim trailing spaces Barry Schwarz <schwarzb@dqel.com> - 2019-01-23 23:39 -0800
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 11:25 -0500
Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 08:34 -0800
Re: Function to trim trailing spaces Barry Schwarz <schwarzb@dqel.com> - 2019-01-24 15:05 -0800
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 18:40 -0500
Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-24 02:29 -0800
Re: Function to trim trailing spaces DFS <nospam@dfs.com> - 2019-01-24 15:06 -0500
Re: Function to trim trailing spaces Mateusz Viste <mateusz@wont.tell> - 2019-01-24 20:07 +0000
Re: Function to trim trailing spaces scott@slp53.sl.home (Scott Lurndal) - 2019-01-24 20:24 +0000
Re: Function to trim trailing spaces Mateusz Viste <mateusz@wont.tell> - 2019-01-24 20:34 +0000
Re: Function to trim trailing spaces scott@slp53.sl.home (Scott Lurndal) - 2019-01-24 21:37 +0000
Re: Function to trim trailing spaces Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2019-01-24 15:34 -0500
Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 13:19 -0800
Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 14:52 -0700
Re: Function to trim trailing spaces James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-24 14:30 -0800
Re: Function to trim trailing spaces Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-01-24 16:59 -0700
Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-24 14:51 -0800
Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 01:06 -0800
Re: Function to trim trailing spaces Keith Thompson <kst-u@mib.org> - 2019-01-24 02:13 -0800
Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 03:46 -0800
Re: Function to trim trailing spaces Anton Shepelev <anton.txt@g{oogle}mail.com> - 2019-01-24 14:56 +0300
Re: Function to trim trailing spaces mark.bluemel@gmail.com - 2019-01-24 05:14 -0800
Re: Function to trim trailing spaces Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-24 18:51 +0000
Re: Function to trim trailing spaces "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-24 20:04 +0100
Re: Function to trim trailing spaces Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-24 20:25 +0000
Re: Function to trim trailing spaces Anton Shepelev <anton.txt@gmail.com> - 2019-01-24 23:50 +0300
Re: Function to trim trailing spaces Anton Shepelev <anton.txt@gmail.com> - 2019-01-24 23:45 +0300
Re: Function to trim trailing spaces Anton Shepelev <anton.txt@gmail.com> - 2019-01-24 23:54 +0300
Re: Function to trim trailing spaces Ralf Damaschke <rwspam@gmx.de> - 2019-01-24 22:43 +0000
Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 10:57 +0000
Re: Function to trim trailing spaces Bart <bc@freeuk.com> - 2019-01-24 23:05 +0000
Function to trim trailing spaces "I Set My Girlfriend's Pantyhose on Fire" <cdalten@gmail.com> - 2019-01-24 03:53 -0800
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-01-23 18:46 -0800 |
| Message-ID | <lnef9222nu.fsf@kst-u.example.com> |
| In reply to | #140136 |
DFS <nospam@dfs.com> writes:
> Needed to right-trim a string (remove trailing spaces), and came up with
> this:
>
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>
>
>
> test_rtrim.c
> ------------------------------------------------
> #include <stdio.h>
>
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>
> int main(int argc, char *argv[])
> {
> char str[100];
>
> printf("\nEnter some text: ");
> fgets(str, sizeof(str), stdin);
> fseek(stdin,0,SEEK_END); //flush stdin
>
> printf("Before: '%s'\n",str);
> rtrim(str);
> printf("After : '%s'\n",str);
> }
> ------------------------------------------------
>
> Seems to work well. Any unobvious pitfalls?
No, the pitfalls are fairly obvious.
Joe Pfeiffer already pointed out that your function doesn't do what it's
supposed to do and that you're missing the required `#include <string.h>`.
Testing the function with a string that has several trailing spaces
might have saved some time.
Your fseek call also doesn't do what the comment says it does. If stdin
is an interactive device (which seems to be the intent), it will simply
fail. There's no point in "flushing" stdin anyway, since you don't
attempt to read from it again before the program finishes.
And a minor point: The newline before the "Enter some text:" message is
pointless.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2019-01-23 23:38 -0500 |
| Message-ID | <Pib2E.185816$JW5.82323@fx46.iad> |
| In reply to | #140138 |
On 1/23/2019 9:46 PM, Keith Thompson wrote:
> DFS <nospam@dfs.com> writes:
>> Needed to right-trim a string (remove trailing spaces), and came up with
>> this:
>>
>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>
>>
>>
>> test_rtrim.c
>> ------------------------------------------------
>> #include <stdio.h>
>>
>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>
>> int main(int argc, char *argv[])
>> {
>> char str[100];
>>
>> printf("\nEnter some text: ");
>> fgets(str, sizeof(str), stdin);
>> fseek(stdin,0,SEEK_END); //flush stdin
>>
>> printf("Before: '%s'\n",str);
>> rtrim(str);
>> printf("After : '%s'\n",str);
>> }
>> ------------------------------------------------
>>
>> Seems to work well. Any unobvious pitfalls?
>
> No, the pitfalls are fairly obvious.
>
> Joe Pfeiffer already pointed out that your function doesn't do what it's
> supposed to do and that you're missing the required `#include <string.h>`.
> Testing the function with a string that has several trailing spaces
> might have saved some time.
I see that now.
Seems I got "lucky", but what I want is correct. Hence the post.
> Your fseek call also doesn't do what the comment says it does. If stdin
> is an interactive device (which seems to be the intent), it will simply
> fail.
It doesn't fail at all, but yes, I know it's not a true flush of stdin.
This snippet is from a larger program, where I keyboard prompt 3x
consecutively.
Without the "flush" after the 1st prompt, the code falls through to the
3rd prompt without letting you enter anything for the 2nd prompt.
Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
through without letting you enter anything).
So I do those flushes after all 3 prompts and it works fine.
> There's no point in "flushing" stdin anyway, since you don't
> attempt to read from it again before the program finishes.
Yeah, it wasn't necessary for this demo.
> And a minor point: The newline before the "Enter some text:" message is
> pointless.
Thanks for the reply.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2019-01-23 23:39 -0800 |
| Message-ID | <i9qi4etluacag0ki0f11ldd1bljgm5n1q2@4ax.com> |
| In reply to | #140139 |
On Wed, 23 Jan 2019 23:38:26 -0500, DFS <nospam@dfs.com> wrote:
>On 1/23/2019 9:46 PM, Keith Thompson wrote:
>> DFS <nospam@dfs.com> writes:
>>> Needed to right-trim a string (remove trailing spaces), and came up with
>>> this:
>>>
>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>
>>>
>>>
>>> test_rtrim.c
>>> ------------------------------------------------
>>> #include <stdio.h>
>>>
>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>
>>> int main(int argc, char *argv[])
>>> {
>>> char str[100];
>>>
>>> printf("\nEnter some text: ");
>>> fgets(str, sizeof(str), stdin);
>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>
>>> printf("Before: '%s'\n",str);
>>> rtrim(str);
>>> printf("After : '%s'\n",str);
>>> }
>>> ------------------------------------------------
>>>
>>> Seems to work well. Any unobvious pitfalls?
>>
>> No, the pitfalls are fairly obvious.
>>
>> Joe Pfeiffer already pointed out that your function doesn't do what it's
>> supposed to do and that you're missing the required `#include <string.h>`.
>> Testing the function with a string that has several trailing spaces
>> might have saved some time.
>
>I see that now.
>
>Seems I got "lucky", but what I want is correct. Hence the post.
>
>
>> Your fseek call also doesn't do what the comment says it does. If stdin
>> is an interactive device (which seems to be the intent), it will simply
>> fail.
>
>It doesn't fail at all, but yes, I know it's not a true flush of stdin.
>
>This snippet is from a larger program, where I keyboard prompt 3x
>consecutively.
>
>Without the "flush" after the 1st prompt, the code falls through to the
>3rd prompt without letting you enter anything for the 2nd prompt.
That is usually caused by residual data in the buffer, in particular
the result of pressing Enter. How are you reading the input?
>Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
>through without letting you enter anything).
What data do you enter in response to the first prompt?
>So I do those flushes after all 3 prompts and it works fine.
Right up until you show the program to your customer, port the program
to a different machine, or apply some update to your OS or run-time
library.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2019-01-24 11:25 -0500 |
| Message-ID | <fDl2E.55962$Rk4.15294@fx32.iad> |
| In reply to | #140143 |
On 1/24/2019 2:39 AM, Barry Schwarz wrote:
> On Wed, 23 Jan 2019 23:38:26 -0500, DFS <nospam@dfs.com> wrote:
>
>> On 1/23/2019 9:46 PM, Keith Thompson wrote:
>>> DFS <nospam@dfs.com> writes:
>>>> Needed to right-trim a string (remove trailing spaces), and came up with
>>>> this:
>>>>
>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>
>>>>
>>>>
>>>> test_rtrim.c
>>>> ------------------------------------------------
>>>> #include <stdio.h>
>>>>
>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>
>>>> int main(int argc, char *argv[])
>>>> {
>>>> char str[100];
>>>>
>>>> printf("\nEnter some text: ");
>>>> fgets(str, sizeof(str), stdin);
>>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>>
>>>> printf("Before: '%s'\n",str);
>>>> rtrim(str);
>>>> printf("After : '%s'\n",str);
>>>> }
>>>> ------------------------------------------------
>>>>
>>>> Seems to work well. Any unobvious pitfalls?
>>>
>>> No, the pitfalls are fairly obvious.
>>>
>>> Joe Pfeiffer already pointed out that your function doesn't do what it's
>>> supposed to do and that you're missing the required `#include <string.h>`.
>>> Testing the function with a string that has several trailing spaces
>>> might have saved some time.
>>
>> I see that now.
>>
>> Seems I got "lucky", but what I want is correct. Hence the post.
>>
>>
>>> Your fseek call also doesn't do what the comment says it does. If stdin
>>> is an interactive device (which seems to be the intent), it will simply
>>> fail.
>>
>> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
>>
>> This snippet is from a larger program, where I keyboard prompt 3x
>> consecutively.
>>
>> Without the "flush" after the 1st prompt, the code falls through to the
>> 3rd prompt without letting you enter anything for the 2nd prompt.
>
> That is usually caused by residual data in the buffer, in particular
> the result of pressing Enter. How are you reading the input?
Enter a number, then hit Enter
>> Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
>> through without letting you enter anything).
>
> What data do you enter in response to the first prompt?
1st prompt: enter a number getchar()
2nd prompt: enter a number getchar()
3rd prompt: enter a filename fgets()
[toc] | [prev] | [next] | [standalone]
| From | mark.bluemel@gmail.com |
|---|---|
| Date | 2019-01-24 08:34 -0800 |
| Message-ID | <a9a243db-b921-4955-b7c1-6484d65d04fd@googlegroups.com> |
| In reply to | #140169 |
On Thursday, 24 January 2019 16:22:44 UTC, DFS wrote: > > 1st prompt: enter a number getchar() > 2nd prompt: enter a number getchar() > 3rd prompt: enter a filename fgets() I suggest reading and understanding the topics covered in <http://c-faq.com/stdio/index.html>. Terminal input in C isn't necessarily easy and mixing different calls without a clear understanding is a recipe for problems. fflush()ing is not necessarily a solution, even if it helps in this case.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2019-01-24 15:05 -0800 |
| Message-ID | <pigk4e967s1jgrgnn9al2pd633bb45g9j4@4ax.com> |
| In reply to | #140169 |
On Thu, 24 Jan 2019 11:25:18 -0500, DFS <nospam@dfs.com> wrote:
>On 1/24/2019 2:39 AM, Barry Schwarz wrote:
>> On Wed, 23 Jan 2019 23:38:26 -0500, DFS <nospam@dfs.com> wrote:
>>
>>> On 1/23/2019 9:46 PM, Keith Thompson wrote:
>>>> DFS <nospam@dfs.com> writes:
>>>>> Needed to right-trim a string (remove trailing spaces), and came up with
>>>>> this:
>>>>>
>>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>>
>>>>>
>>>>>
>>>>> test_rtrim.c
>>>>> ------------------------------------------------
>>>>> #include <stdio.h>
>>>>>
>>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>>
>>>>> int main(int argc, char *argv[])
>>>>> {
>>>>> char str[100];
>>>>>
>>>>> printf("\nEnter some text: ");
>>>>> fgets(str, sizeof(str), stdin);
>>>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>>>
>>>>> printf("Before: '%s'\n",str);
>>>>> rtrim(str);
>>>>> printf("After : '%s'\n",str);
>>>>> }
>>>>> ------------------------------------------------
>>>>>
>>>>> Seems to work well. Any unobvious pitfalls?
>>>>
>>>> No, the pitfalls are fairly obvious.
>>>>
>>>> Joe Pfeiffer already pointed out that your function doesn't do what it's
>>>> supposed to do and that you're missing the required `#include <string.h>`.
>>>> Testing the function with a string that has several trailing spaces
>>>> might have saved some time.
>>>
>>> I see that now.
>>>
>>> Seems I got "lucky", but what I want is correct. Hence the post.
>>>
>>>
>>>> Your fseek call also doesn't do what the comment says it does. If stdin
>>>> is an interactive device (which seems to be the intent), it will simply
>>>> fail.
>>>
>>> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
>>>
>>> This snippet is from a larger program, where I keyboard prompt 3x
>>> consecutively.
>>>
>>> Without the "flush" after the 1st prompt, the code falls through to the
>>> 3rd prompt without letting you enter anything for the 2nd prompt.
>>
>> That is usually caused by residual data in the buffer, in particular
>> the result of pressing Enter. How are you reading the input?
>
>Enter a number, then hit Enter
>
>
>>> Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
>>> through without letting you enter anything).
>>
>> What data do you enter in response to the first prompt?
>
>
>1st prompt: enter a number getchar()
>2nd prompt: enter a number getchar()
>3rd prompt: enter a filename fgets()
Since getchar extracts a single character from the buffer, can we
assume that you are entering single digit values?
If so, you type in one digit (let's assume '1') and then you press
Enter. The buffer now contains two characters, '1' and '\n'. getchar
extracts the '1' and leaves the '\n' in the buffer. You print the
next prompt and call getchar again (expecting it to wait for more
input). However, getchar is quite willing to extract the '\n' and
return it to your program. Since getchar has returned, your program
happily moves on to the third prompt.
The two most common portable methods of avoiding this problem are:
1 - Call getchar after obtaining the data you want but ignore the
return value. But this will not help in this case if the user types
in two digits.
2 - Extract the input into a string using fgets (which will extract
the \n also) and convert it to the numeric form you need using either
sscanf or one the strto... functions. This is the preferred method if
you want to perform validity checks after extracting the data.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2019-01-24 18:40 -0500 |
| Message-ID | <U%r2E.35655$q54.2702@fx15.iad> |
| In reply to | #140214 |
On 1/24/2019 6:05 PM, Barry Schwarz wrote:
> On Thu, 24 Jan 2019 11:25:18 -0500, DFS <nospam@dfs.com> wrote:
>
>> On 1/24/2019 2:39 AM, Barry Schwarz wrote:
>>> On Wed, 23 Jan 2019 23:38:26 -0500, DFS <nospam@dfs.com> wrote:
>>>
>>>> On 1/23/2019 9:46 PM, Keith Thompson wrote:
>>>>> DFS <nospam@dfs.com> writes:
>>>>>> Needed to right-trim a string (remove trailing spaces), and came up with
>>>>>> this:
>>>>>>
>>>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>>>
>>>>>>
>>>>>>
>>>>>> test_rtrim.c
>>>>>> ------------------------------------------------
>>>>>> #include <stdio.h>
>>>>>>
>>>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>>>
>>>>>> int main(int argc, char *argv[])
>>>>>> {
>>>>>> char str[100];
>>>>>>
>>>>>> printf("\nEnter some text: ");
>>>>>> fgets(str, sizeof(str), stdin);
>>>>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>>>>
>>>>>> printf("Before: '%s'\n",str);
>>>>>> rtrim(str);
>>>>>> printf("After : '%s'\n",str);
>>>>>> }
>>>>>> ------------------------------------------------
>>>>>>
>>>>>> Seems to work well. Any unobvious pitfalls?
>>>>>
>>>>> No, the pitfalls are fairly obvious.
>>>>>
>>>>> Joe Pfeiffer already pointed out that your function doesn't do what it's
>>>>> supposed to do and that you're missing the required `#include <string.h>`.
>>>>> Testing the function with a string that has several trailing spaces
>>>>> might have saved some time.
>>>>
>>>> I see that now.
>>>>
>>>> Seems I got "lucky", but what I want is correct. Hence the post.
>>>>
>>>>
>>>>> Your fseek call also doesn't do what the comment says it does. If stdin
>>>>> is an interactive device (which seems to be the intent), it will simply
>>>>> fail.
>>>>
>>>> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
>>>>
>>>> This snippet is from a larger program, where I keyboard prompt 3x
>>>> consecutively.
>>>>
>>>> Without the "flush" after the 1st prompt, the code falls through to the
>>>> 3rd prompt without letting you enter anything for the 2nd prompt.
>>>
>>> That is usually caused by residual data in the buffer, in particular
>>> the result of pressing Enter. How are you reading the input?
>>
>> Enter a number, then hit Enter
>>
>>
>>>> Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
>>>> through without letting you enter anything).
>>>
>>> What data do you enter in response to the first prompt?
>>
>>
>> 1st prompt: enter a number getchar()
>> 2nd prompt: enter a number getchar()
>> 3rd prompt: enter a filename fgets()
>
> Since getchar extracts a single character from the buffer, can we
> assume that you are entering single digit values?
Yes. 1 or 2 (sometimes also 3 or 4).
Currently no validation on the entered value.
> If so, you type in one digit (let's assume '1') and then you press
> Enter. The buffer now contains two characters, '1' and '\n'. getchar
> extracts the '1' and leaves the '\n' in the buffer. You print the
> next prompt and call getchar again (expecting it to wait for more
> input). However, getchar is quite willing to extract the '\n' and
> return it to your program. Since getchar has returned, your program
> happily moves on to the third prompt.
>
> The two most common portable methods of avoiding this problem are:
> 1 - Call getchar after obtaining the data you want but ignore the
> return value. But this will not help in this case if the user types
> in two digits.
> 2 - Extract the input into a string using fgets (which will extract
> the \n also) and convert it to the numeric form you need using either
> sscanf or one the strto... functions. This is the preferred method if
> you want to perform validity checks after extracting the data.
Good answer. Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-01-24 02:29 -0800 |
| Message-ID | <ln1s521h8v.fsf@kst-u.example.com> |
| In reply to | #140139 |
DFS <nospam@dfs.com> writes:
> On 1/23/2019 9:46 PM, Keith Thompson wrote:
>> DFS <nospam@dfs.com> writes:
>>> Needed to right-trim a string (remove trailing spaces), and came up with
>>> this:
>>>
>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>
>>> test_rtrim.c
>>> ------------------------------------------------
>>> #include <stdio.h>
>>>
>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>
>>> int main(int argc, char *argv[])
>>> {
>>> char str[100];
>>>
>>> printf("\nEnter some text: ");
>>> fgets(str, sizeof(str), stdin);
>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>
>>> printf("Before: '%s'\n",str);
>>> rtrim(str);
>>> printf("After : '%s'\n",str);
>>> }
>>> ------------------------------------------------
>>>
>>> Seems to work well. Any unobvious pitfalls?
[...]
>> Your fseek call also doesn't do what the comment says it does. If stdin
>> is an interactive device (which seems to be the intent), it will simply
>> fail.
>
> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
In the program you posted, you can't tell whether it fails because you
don't test the result.
> This snippet is from a larger program, where I keyboard prompt 3x
> consecutively.
>
> Without the "flush" after the 1st prompt, the code falls through to
> the 3rd prompt without letting you enter anything for the 2nd prompt.
>
> Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
> through without letting you enter anything).
>
> So I do those flushes after all 3 prompts and it works fine.
That's odd. Since you talk about keyboard prompts, I presume
that stdin is associated with a keyboard. I would have expected
fseek(stdin, ...) to fail in that case.
Can you show a (possibly reduced version of) your program in which it
works as you say it does?
I just did a test. On Ubuntu Linux, using the above program, fseek()
fails and sets errno to 29 (ESPIPE, Illegal seek). On Windows
(compiling with x86_64-w64-mingw32-gcc) the fseek() call succeeds,
but I'm not sure what it does.
If you want to discard input (for example, all characters up to and
including the next newline), it's probably better to read and discard
them
int c; do c = getchar(); while (c != EOF && c != '\n');
rather than playing tricks with fseek(). (It's not necessary in your
small example because fgets() has already read the newline -- assuming
the input line isn't too long.)
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2019-01-24 15:06 -0500 |
| Message-ID | <pTo2E.115832$Fj3.56469@fx06.iad> |
| In reply to | #140150 |
On 1/24/2019 5:29 AM, Keith Thompson wrote:
> DFS <nospam@dfs.com> writes:
>> On 1/23/2019 9:46 PM, Keith Thompson wrote:
>>> DFS <nospam@dfs.com> writes:
>>>> Needed to right-trim a string (remove trailing spaces), and came up with
>>>> this:
>>>>
>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>
>>>> test_rtrim.c
>>>> ------------------------------------------------
>>>> #include <stdio.h>
>>>>
>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>
>>>> int main(int argc, char *argv[])
>>>> {
>>>> char str[100];
>>>>
>>>> printf("\nEnter some text: ");
>>>> fgets(str, sizeof(str), stdin);
>>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>>
>>>> printf("Before: '%s'\n",str);
>>>> rtrim(str);
>>>> printf("After : '%s'\n",str);
>>>> }
>>>> ------------------------------------------------
>>>>
>>>> Seems to work well. Any unobvious pitfalls?
> [...]
>>> Your fseek call also doesn't do what the comment says it does. If stdin
>>> is an interactive device (which seems to be the intent), it will simply
>>> fail.
>>
>> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
>
> In the program you posted, you can't tell whether it fails because you
> don't test the result.
How could fseek(stdin,0,SEEK_END); ever fail?
>> This snippet is from a larger program, where I keyboard prompt 3x
>> consecutively.
>>
>> Without the "flush" after the 1st prompt, the code falls through to
>> the 3rd prompt without letting you enter anything for the 2nd prompt.
>>
>> Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
>> through without letting you enter anything).
>>
>> So I do those flushes after all 3 prompts and it works fine.
>
> That's odd. Since you talk about keyboard prompts, I presume
> that stdin is associated with a keyboard. I would have expected
> fseek(stdin, ...) to fail in that case.
>
> Can you show a (possibly reduced version of) your program in which it
> works as you say it does?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void rtrim(char * s) {s[strlen(s)-1]='\0';}
/*
above is the original rtrim(), subject of this thread. I've since
replaced it with:
void rtrim(char * s)
{
int i=0, index=0;
while(s[i] != '\0')
{
if(s[i]!=' ' && s[i]!='\t' && s[i]!='\n') {index= i;}
i++;
}
s[index+1]='\0';
}
*/
int main(int argc, char *argv[])
{
//vars
char fileop[8];
char separator[2];
char filein[100];
int i;
FILE *fin;
//get values from keyboard
fseek(stdin,0,SEEK_END);
printf("Choose file operation:\n1. Summary\n2. Data Operations\n");
i = getchar();
memset(fileop, '\0', sizeof(fileop));
if (i=='1') {strcpy(fileop,"summary");}
if (i=='2') {strcpy(fileop,"data");}
fseek(stdin,0,SEEK_END);
printf("\nChoose field separator:\n");
printf("1. pipe |\n2. pound #\n3. tilde ~\n4. comma ,\n");
i = getchar();
memset(separator, '\0', 2);
if (i=='1') {strcpy(separator,"|");}
if (i=='2') {strcpy(separator,"#");}
if (i=='3') {strcpy(separator,"~");}
if (i=='4') {strcpy(separator,",");}
fseek(stdin,0,SEEK_END);
printf("\nEnter name of .csv file:\n");
fgets(filein, sizeof(filein), stdin);
rtrim(filein);
fseek(stdin,0,SEEK_END);
//that's all 3 keyboard prompts. After this I open the .csv "filein",
count headers and data rows, print the results, then close the file and exit
}
> I just did a test. On Ubuntu Linux, using the above program, fseek()
> fails and sets errno to 29 (ESPIPE, Illegal seek). On Windows
> (compiling with x86_64-w64-mingw32-gcc) the fseek() call succeeds,
> but I'm not sure what it does.
>
> If you want to discard input (for example, all characters up to and
> including the next newline), it's probably better to read and discard
> them
>
> int c; do c = getchar(); while (c != EOF && c != '\n');
>
> rather than playing tricks with fseek(). (It's not necessary in your
> small example because fgets() has already read the newline -- assuming
> the input line isn't too long.)
>
> [...]
FYI: tcc 0.9.26 on Windows
$tcc -Wall csvmgr.c -o csvmgr.exe
compiles with no warnings
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@wont.tell> |
|---|---|
| Date | 2019-01-24 20:07 +0000 |
| Message-ID | <5c4a1af5$0$3539$426a74cc@news.free.fr> |
| In reply to | #140188 |
On Thu, 24 Jan 2019 15:06:29 -0500, DFS wrote: >> In the program you posted, you can't tell whether it fails because you >> don't test the result. > > How could fseek(stdin,0,SEEK_END); ever fail? It could fail if you closed stdin. That's something daemons commonly do. Mateusz
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-01-24 20:24 +0000 |
| Message-ID | <1ap2E.215322$Z45.42723@fx44.iad> |
| In reply to | #140190 |
Mateusz Viste <mateusz@wont.tell> writes: >On Thu, 24 Jan 2019 15:06:29 -0500, DFS wrote: >>> In the program you posted, you can't tell whether it fails because you >>> don't test the result. >> >> How could fseek(stdin,0,SEEK_END); ever fail? > >It could fail if you closed stdin. That's something daemons commonly do. Most demons will re-open "/dev/null" on fd0.
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@wont.tell> |
|---|---|
| Date | 2019-01-24 20:34 +0000 |
| Message-ID | <5c4a2152$0$20331$426a74cc@news.free.fr> |
| In reply to | #140194 |
On Thu, 24 Jan 2019 20:24:29 +0000, Scott Lurndal wrote: > Mateusz Viste <mateusz@wont.tell> writes: >>On Thu, 24 Jan 2019 15:06:29 -0500, DFS wrote: >>>> In the program you posted, you can't tell whether it fails because >>>> you don't test the result. >>> >>> How could fseek(stdin,0,SEEK_END); ever fail? >> >>It could fail if you closed stdin. That's something daemons commonly do. > > Most demons will re-open "/dev/null" on fd0. This only means that fseek() would "mostly work". Is that good enough? I think it is not. Mateusz
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-01-24 21:37 +0000 |
| Message-ID | <Teq2E.86129$375.28604@fx40.iad> |
| In reply to | #140197 |
Mateusz Viste <mateusz@wont.tell> writes: >On Thu, 24 Jan 2019 20:24:29 +0000, Scott Lurndal wrote: >> Mateusz Viste <mateusz@wont.tell> writes: >>>On Thu, 24 Jan 2019 15:06:29 -0500, DFS wrote: >>>>> In the program you posted, you can't tell whether it fails because >>>>> you don't test the result. >>>> >>>> How could fseek(stdin,0,SEEK_END); ever fail? >>> >>>It could fail if you closed stdin. That's something daemons commonly do. >> >> Most demons will re-open "/dev/null" on fd0. > >This only means that fseek() would "mostly work". Is that good enough? I >think it is not. I dunno. In over forty years of C and Posix programming, I've never needed to use fseek(3) at all. seek(2) and later lseek(2) yes, fseek(3) never. But then, I typically avoid stdio for most real world usage scenarios; favoring mmap() or pread(2)/pwrite(2) for most cases.
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2019-01-24 15:34 -0500 |
| Message-ID | <q2d7fq$s9f$1@dont-email.me> |
| In reply to | #140188 |
DFS wrote:
> On 1/24/2019 5:29 AM, Keith Thompson wrote:
>> DFS <nospam@dfs.com> writes:
>>> On 1/23/2019 9:46 PM, Keith Thompson wrote:
>>>> DFS <nospam@dfs.com> writes:
>>>>> Needed to right-trim a string (remove trailing spaces), and came up
>>>>> with this:
>>>>>
>>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>>
>>>>> test_rtrim.c
>>>>> ------------------------------------------------
>>>>> #include <stdio.h>
>>>>>
>>>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>>>>>
>>>>> int main(int argc, char *argv[])
>>>>> {
>>>>> char str[100];
>>>>>
>>>>> printf("\nEnter some text: ");
>>>>> fgets(str, sizeof(str), stdin);
>>>>> fseek(stdin,0,SEEK_END); //flush stdin
>>>>>
>>>>> printf("Before: '%s'\n",str);
>>>>> rtrim(str);
>>>>> printf("After : '%s'\n",str);
>>>>> }
>>>>> ------------------------------------------------
>>>>>
>>>>> Seems to work well. Any unobvious pitfalls?
>> [...]
>>>> Your fseek call also doesn't do what the comment says it does. If
>>>> stdin is an interactive device (which seems to be the intent), it will
>>>> simply fail.
>>>
>>> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
>>
>> In the program you posted, you can't tell whether it fails because you
>> don't test the result.
>
>
> How could fseek(stdin,0,SEEK_END); ever fail?
C11:
7.21.9.2 The fseek function
Synopsis
1 #include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);
Description
2 The fseek function sets the file position indicator for the stream
pointed to by stream.
...
Returns
6 The fseek function returns nonzero only for a request that cannot be
satisfied.
One implementation:
NAME
fgetpos, fseek, fsetpos, ftell, rewind - reposition a stream
SYNOPSIS
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
DESCRIPTION
The fseek() function sets the file position indicator for the
stream pointed to by stream.
...
ERRORS
EBADF The stream specified is not a seekable stream.
>>> This snippet is from a larger program, where I keyboard prompt 3x
>>> consecutively.
>>>
>>> Without the "flush" after the 1st prompt, the code falls through to
>>> the 3rd prompt without letting you enter anything for the 2nd prompt.
>>>
>>> Without the "flush" after the 2nd prompt, the 3rd prompts fails (falls
>>> through without letting you enter anything).
>>>
>>> So I do those flushes after all 3 prompts and it works fine.
>>
>> That's odd. Since you talk about keyboard prompts, I presume
>> that stdin is associated with a keyboard. I would have expected
>> fseek(stdin, ...) to fail in that case.
>>
>> Can you show a (possibly reduced version of) your program in which it
>> works as you say it does?
>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>
> /*
> above is the original rtrim(), subject of this thread. I've since
> replaced it with:
>
> void rtrim(char * s)
> {
> int i=0, index=0;
> while(s[i] != '\0')
> {
> if(s[i]!=' ' && s[i]!='\t' && s[i]!='\n') {index= i;}
> i++;
> }
> s[index+1]='\0';
> }
> */
>
>
> int main(int argc, char *argv[])
> {
>
> //vars
> char fileop[8];
> char separator[2];
> char filein[100];
> int i;
> FILE *fin;
>
> //get values from keyboard
> fseek(stdin,0,SEEK_END);
>
> printf("Choose file operation:\n1. Summary\n2. Data Operations\n");
> i = getchar();
> memset(fileop, '\0', sizeof(fileop));
> if (i=='1') {strcpy(fileop,"summary");}
> if (i=='2') {strcpy(fileop,"data");}
> fseek(stdin,0,SEEK_END);
>
> printf("\nChoose field separator:\n");
> printf("1. pipe |\n2. pound #\n3. tilde ~\n4. comma ,\n");
> i = getchar();
> memset(separator, '\0', 2);
> if (i=='1') {strcpy(separator,"|");}
> if (i=='2') {strcpy(separator,"#");}
> if (i=='3') {strcpy(separator,"~");}
> if (i=='4') {strcpy(separator,",");}
> fseek(stdin,0,SEEK_END);
>
> printf("\nEnter name of .csv file:\n");
> fgets(filein, sizeof(filein), stdin);
> rtrim(filein);
> fseek(stdin,0,SEEK_END);
>
>
> //that's all 3 keyboard prompts. After this I open the .csv "filein",
> count headers and data rows, print the results, then close the file and
> exit
>
> }
>
>
>
>
>> I just did a test. On Ubuntu Linux, using the above program, fseek()
>> fails and sets errno to 29 (ESPIPE, Illegal seek). On Windows
>> (compiling with x86_64-w64-mingw32-gcc) the fseek() call succeeds,
>> but I'm not sure what it does.
>>
>> If you want to discard input (for example, all characters up to and
>> including the next newline), it's probably better to read and discard
>> them
>>
>> int c; do c = getchar(); while (c != EOF && c != '\n');
>>
>> rather than playing tricks with fseek(). (It's not necessary in your
>> small example because fgets() has already read the newline -- assuming
>> the input line isn't too long.)
>>
>> [...]
>
>
> FYI: tcc 0.9.26 on Windows
>
> $tcc -Wall csvmgr.c -o csvmgr.exe
>
> compiles with no warnings
--
Lew Pitcher
"In Skills, We Trust"
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-01-24 13:19 -0800 |
| Message-ID | <05292e40-78d7-4964-8d1c-ffad7d8eb041@googlegroups.com> |
| In reply to | #140188 |
On Thursday, January 24, 2019 at 3:04:46 PM UTC-5, DFS wrote:
> On 1/24/2019 5:29 AM, Keith Thompson wrote:
> > DFS <nospam@dfs.com> writes:
> >> On 1/23/2019 9:46 PM, Keith Thompson wrote:
> >>> DFS <nospam@dfs.com> writes:
> >>>> Needed to right-trim a string (remove trailing spaces), and came up with
> >>>> this:
> >>>>
> >>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
> >>>>
> >>>> test_rtrim.c
> >>>> ------------------------------------------------
> >>>> #include <stdio.h>
> >>>>
> >>>> void rtrim(char * s) {s[strlen(s)-1]='\0';}
> >>>>
> >>>> int main(int argc, char *argv[])
> >>>> {
> >>>> char str[100];
> >>>>
> >>>> printf("\nEnter some text: ");
> >>>> fgets(str, sizeof(str), stdin);
> >>>> fseek(stdin,0,SEEK_END); //flush stdin
> >>>>
> >>>> printf("Before: '%s'\n",str);
> >>>> rtrim(str);
> >>>> printf("After : '%s'\n",str);
> >>>> }
> >>>> ------------------------------------------------
> >>>>
> >>>> Seems to work well. Any unobvious pitfalls?
> > [...]
> >>> Your fseek call also doesn't do what the comment says it does. If stdin
> >>> is an interactive device (which seems to be the intent), it will simply
> >>> fail.
> >>
> >> It doesn't fail at all, but yes, I know it's not a true flush of stdin.
> >
> > In the program you posted, you can't tell whether it fails because you
> > don't test the result.
>
>
> How could fseek(stdin,0,SEEK_END); ever fail?
Footnote 268 says "Setting the file position indicator to end-of-file,
as with fseek(file, 0, SEEK_END), has undefined behavior for a binary
stream (because of possible trailing null characters) or for any stream
with state-dependent encoding that does not assuredly end in the initial
shift state."
"A binary stream need not meaningfully support fseek calls with a whence
value of SEEK_END." (7.21.9.2p3).
For example, The Open Group Base Specifications Issue 7, 2018 edition
IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008) lists the
following possible reasons for the above call to fseek() to fail:
" [ESPIPE]
[CX] The file descriptor underlying stream is associated with a
pipe, FIFO, or socket.
The fseek() ... functions may fail if:
[ENXIO]
[CX] A request was made of a nonexistent device, or the request
was outside the capabilities of the device."
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2019-01-24 14:52 -0700 |
| Message-ID | <1b5zud4tac.fsf@pfeifferfamily.net> |
| In reply to | #140188 |
DFS <nospam@dfs.com> writes:
>
> How could fseek(stdin,0,SEEK_END); ever fail?
From the man page:
ERRORS
EINVAL The whence argument to fseek() was not SEEK_SET, SEEK_END, or SEEK_CUR. Or: the
resulting file offset would be negative.
ESPIPE The file descriptor underlying stream is not seekable (e.g., it refers to a pipe,
FIFO, or socket).
See the second case.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-01-24 14:30 -0800 |
| Message-ID | <ccea22f8-fadf-41f4-baed-47e427886734@googlegroups.com> |
| In reply to | #140208 |
On Thursday, January 24, 2019 at 4:53:07 PM UTC-5, Joe Pfeiffer wrote: > DFS <nospam@dfs.com> writes: > > > > How could fseek(stdin,0,SEEK_END); ever fail? > > From the man page: > > ERRORS > EINVAL The whence argument to fseek() was not SEEK_SET, SEEK_END, or SEEK_CUR. The whence argument is SEEK_END. Or: the > resulting file offset would be negative. How could the file offset for fseek(file, 0, SEEK_END) be negative?
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2019-01-24 16:59 -0700 |
| Message-ID | <1b1s514nfx.fsf@pfeifferfamily.net> |
| In reply to | #140209 |
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
> On Thursday, January 24, 2019 at 4:53:07 PM UTC-5, Joe Pfeiffer wrote:
>> DFS <nospam@dfs.com> writes:
>> >
>> > How could fseek(stdin,0,SEEK_END); ever fail?
>>
>> From the man page:
>>
>> ERRORS
>> EINVAL The whence argument to fseek() was not SEEK_SET, SEEK_END, or SEEK_CUR.
>
> The whence argument is SEEK_END.
>
> Or: the
>> resulting file offset would be negative.
>
> How could the file offset for fseek(file, 0, SEEK_END) be negative?
I was referring to
ESPIPE The file descriptor underlying stream is not seekable (e.g., it refers to a pipe,
FIFO, or socket).
as the second case.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-01-24 14:51 -0800 |
| Message-ID | <lnwomtzn1u.fsf@kst-u.example.com> |
| In reply to | #140188 |
DFS <nospam@dfs.com> writes:
[...]
> How could fseek(stdin,0,SEEK_END); ever fail?
On my system (Ubuntu), it consistently fails, returning -1 and
setting errno to ESPIPE (Illegal seek) -- because stdin is not
a seekable stream when it's connected to the keyboard. (I'm not
entirely sure what that fseek is supposed to do.)
I tried your latest program (see the parent of this article) on
Windows, compiling with x86_64-w64-mingw32-gcc.exe under Cygwin. The
fseek() calls succeed, but I don't see the initial prompt.
If you've read a partial line of input, as you've done with your
first getchar() call, the portable way to discard the rest of the
line is to read characters until you encounter a newline or EOF.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | mark.bluemel@gmail.com |
|---|---|
| Date | 2019-01-24 01:06 -0800 |
| Message-ID | <549145a8-950f-4027-9495-b909ab34a6a9@googlegroups.com> |
| In reply to | #140136 |
On Thursday, 24 January 2019 01:59:58 UTC, DFS wrote:
> Needed to right-trim a string (remove trailing spaces), and came up with
> this:
>
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>
>
>
> test_rtrim.c
> ------------------------------------------------
> #include <stdio.h>
>
> void rtrim(char * s) {s[strlen(s)-1]='\0';}
>
> int main(int argc, char *argv[])
> {
> char str[100];
>
> printf("\nEnter some text: ");
> fgets(str, sizeof(str), stdin);
> fseek(stdin,0,SEEK_END); //flush stdin
>
> printf("Before: '%s'\n",str);
> rtrim(str);
> printf("After : '%s'\n",str);
> }
> ------------------------------------------------
>
> Seems to work well. Any unobvious pitfalls?
As already mentioned, there are enough obvious ones to
be going on with.
If ever there was an example of the need for Test
Driven Development, this looks like it - not because
the task is hard, but because programmers need to be
made to think.
Please tell us what happens when you run the following
snippets.
char *s = "my dog has fleas";
printf("Before: '%s'\n",str);
rtrim(str);
printf("After : '%s'\n",str);
On some platforms/compilers, it's quite likely to fail dramatically as
string constants are read-only. If it doesn't in your environment, that's
down to (bad) luck.
char *s = strdup("my dog has fleas");
printf("Before: '%s'\n",str);
rtrim(str);
printf("After : '%s'\n",str);
char *s = strdup("my dog has fleas ");
printf("Before: '%s'\n",str);
rtrim(str);
printf("After : '%s'\n",str);
char *s = strdup(" ");
printf("Before: '%s'\n",str);
rtrim(str);
printf("After : '%s'\n",str);
char *s = strdup(" ");
printf("Before: '%s'\n",str);
rtrim(str);
printf("After : '%s'\n",str);
Did that do what you really wanted?
Here's my 10-minute simplistic hack to do the job.
The rtrim() function is not elegant, but suffices, and my main
point is to show some basic ideas about how you could use testing.
(My more complete example would test the results against expected
values).
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *rtrim(char *str) {
char * result = strdup(str);
int i = strlen(result);
for (i = i-1; i >= 0 && result[i]==' '; i--) {
result[i] = 0;
}
return result;
}
int main(void) {
char * testStrings[] = {
"my dog has no spaces",
"my dog has one space ",
"my dog has lots of spaces ",
" ",
" "
};
int i;
for (i = 0; i < sizeof(testStrings)/sizeof(testStrings[0]); i++) {
char *trimmed = rtrim(testStrings[i]);
printf("before '%s' after '%s'\n", testStrings[i], trimmed);
free(trimmed);
}
}
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web