|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I have a function named getword that read every single input from std.
input. WHAT I WANTED: I want it read the word if it has less than or equal to 30 characters. Anything else beyond that should be discarded and it should ask the user for new input. Ctrl-D should exit from the program. WHAT I GOT: It reads anything beyond 30 characters as the next word :\ and I have to press Ctrl-D two times to exit from the program. /* This program will simply create an array of pointers to integers * and will fill it with some values while using malloc to create * pointers to fill the array and then will print the values pointed * by those pointers * * version 1.1 * */ #include <stdio.h> #include <ctype.h> enum { MAX = 30 }; int getword( char *, int ); int main( void ) { char word[MAX]; while( getword( word, MAX ) ) { printf( "----------> %s\n", word ); } return 0; } /* A program that takes a single word as input. It will discard * the whole input if it contains anything other than the 26 alphabets * of English. If the input word contains more than 30 letters then only * the extra letters will be discarded . For general purpose usage of * English it does not make any sense to use a word larger than this size. * Nearly every general purpose word can be expressed in a word with less * than or equal to 30 letters. * */ int getword( char *word, int max_length ) { int c; char *w = word; while( isspace( c = getchar() ) ) { ; } if( isalpha( c ) ) { *w++ = c; } while( --max_length && (c = getchar()) ) { if( isalpha( c ) ) { *w++ = c; } else if( isspace( c ) || c == EOF) { *w = '\0'; break; } else { return 0; } } *w = '\0'; return word[0]; } ================ OUTPUT ===================== [arnuld@raj C]$ gcc -ansi -pedantic -Wall -Wextra test.c [arnuld@raj C]$ ./a.out like ----------> like this ----------> this lllllllllllllllpppppppppppppqqqqqqqqqqqqqqqqqqqqqq qqqqqqqqqqqqqqqqqqqpppppppppppdddddddddddddddddddd dddddd ----------> lllllllllllllllpppppppppppppqq ----------> qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq ----------> qqqqqqqqqpppppppppppdddddddddd ----------> dddddddddddddddd [arnuld@raj C]$ -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
arnuld <sunrise@see.sigs.invalid> writes:
> I have a function named getword that read every single input from std. > input. > > WHAT I WANTED: I want it read the word if it has less than or equal to 30 > characters. Be careful with your counts. Most people would say that a 30 character words needs a 31 character array to store it. I'd say your code accepts words up to and including 29 characters. > Anything else beyond that should be discarded and it should > ask the user for new input. Ctrl-D should exit from the program. This is underspecified. At least in one sense, if "anything else beyond" has been discarded, how can there be any more input? Maybe you want to throw away any more input on that line? > WHAT I GOT: It reads anything beyond 30 characters as the next word :\ and > I have to press Ctrl-D two times to exit from the program. You can't change the Ctrl-D behaviour without resorting to some serious OS-specific code. You may need a screen library like ncurses if you go much further. -- Ben. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
> > I have a function named getword that read every single input from > std. input. > > WHAT I WANTED: I want it read the word if it has less than or > equal to 30 characters. Anything else beyond that should be > discarded and it should ask the user for new input. Ctrl-D should > exit from the program. > > WHAT I GOT: It reads anything beyond 30 characters as the next > word :\ and I have to press Ctrl-D two times to exit from the > program. Try this. To generate EOF press ctl-D at line beginning. /* Get the next word consisting of alpha chars */ /* Return the terminating character (or EOF) */ /* Downshift the acquired word */ static int nextword(FILE *f, char *buffer, int max) { int i, ch; while ((!isalpha(ch = getc(f))) && (ch != EOF)) continue; if (EOF != ch) { i = 0; max--; do { if (i < max) buffer[i++] = tolower(ch); } while (isalpha(ch = getc(f))); buffer[i] = '\0'; /* terminate string */ } return ch; } /* nextword */ (It's part of wdfreq.c, in the hashlib package.) -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com ** |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
>> On Wed, 07 May 2008 12:35:35 -0400, CBFalconer wrote: > > > >> Try this. To generate EOF press ctl-D at line beginning. >> >> /* Get the next word consisting of alpha chars */ >> /* Return the terminating character (or EOF) */ >> /* Downshift the acquired word */ >> static int nextword(FILE *f, char *buffer, int max) >> { >> ...SNIP... > > one more nit, why use static int instead of int as return value ? > The function is declared static, not the int! -- Ian Collins. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
By the way, your clock appears to be rather fast. Date: Fri, 09 May 2008 02:36:41 +0500 It's only Thursday afternoon here and no one is ahead of us! -- Ian Collins. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
> On Thu, 08 May 2008 17:00:03 +1200, Ian Collins wrote:
> The function is declared static, not the int! oops! So, is it a good practice or or a C style to make every function/variable static if I have only source file ? -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
> On Wed, 07 May 2008 10:58:41 +0100, Ben Bacarisse wrote:
> Be careful with your counts. Most people would say that a 30 > character words needs a 31 character array to store it. I'd say > your code accepts words up to and including 29 characters. with maxlength = 30, my function reads 30 characters plus the '\0': int getword( char *word, int max_length ) { int c; char *w = word; while( !( isalpha( c = getchar() ) ) && EOF != c ) { continue; } do { if( isalpha( c ) ) { *w++ = c; } else if( isspace( c ) || c == EOF) { *w = '\0'; break; } else { return 0; } } while( --max_length && (c = getchar()) ); *w = '\0'; return word[0]; } -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
>> On Thu, 08 May 2008 17:00:03 +1200, Ian Collins wrote: > >> The function is declared static, not the int! > > oops! > > So, is it a good practice or or a C style to make every function/variable > static if I have only source file ? > There's no harm in doing so. -- Ian Collins. |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
Ian Collins said:
> arnuld wrote: >>> On Thu, 08 May 2008 17:00:03 +1200, Ian Collins wrote: >> >>> The function is declared static, not the int! >> >> oops! >> >> So, is it a good practice or or a C style to make every >> function/variable static if I have only source file ? >> > There's no harm in doing so. ....except for main, of course! -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
> I have a function named getword that read every single input from std. > input. > > WHAT I WANTED: I want it read the word if it has less than or equal to 30 > characters. Anything else beyond that should be discarded and it should > ask the user for new input. Try this: /* BEGIN fscanf_input.c */ /* ** There are only three different values ** that can be assigned to the int variable rc, ** from the fscanf calls in this program; ** They are: ** EOF ** 0 ** 1 ** If rc equals EOF, then the end of file was reached, ** or there is some other input problem; ** ferror and feof can be used to distinguish which. ** If rc equals 0, then an empty line ** (a line consisting only of one newline character) ** was entered, and the array contains garbage values. ** If rc equals 1, then there is a string in the array. ** Up to LENGTH number of characters are read ** from a line of a text stream ** and written to a string in an array. ** The newline character in the text line is replaced ** by a null character in the array. ** If the line is longer than LENGTH, ** then the extra characters are discarded. */ #include <stdio.h> #define LENGTH 30 #define str(x) # x #define xstr(x) str(x) int main(void) { int rc; char array[LENGTH + 1]; puts("The LENGTH macro is " xstr(LENGTH) "."); do { fputs("Enter any line of text to continue,\n" "or just hit the Enter key to quit:", stdout); fflush(stdout); rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array); if (!feof(stdin)) { getc(stdin); } if (rc == 0) { array[0] = '\0'; } if (rc == EOF) { puts("rc equals EOF"); } else { printf("rc is %d. Your string is:%s\n\n", rc, array); } } while (rc == 1); return 0; } /* END fscanf_input.c */ -- pete |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
arnuld <sunrise@see.sigs.invalid> writes:
>> On Wed, 07 May 2008 10:58:41 +0100, Ben Bacarisse wrote: > >> Be careful with your counts. Most people would say that a 30 >> character words needs a 31 character array to store it. I'd say >> your code accepts words up to and including 29 characters. > > with maxlength = 30, my function reads 30 characters plus the '\0': Neither you nor I are in doubt about what the function does -- I was just asking that you be careful in your comments. For example, the above remark is again vague: (a) the function may read many more than 30 characters; (b) it does not read the '\0'; (c) it may store up to 30 chars; (d) the result may be a string as long as 29. Lots of errors can come from readers believing a program's incorrect comments or from misunderstanding an ambiguous comment. I was just suggesting that you take care when writing them. -- Ben. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
arnuld <sunrise@see.sigs.invalid> writes:
<snip> > while( getword2( word, MAX ) ) > { > printf( "----------> %s\n", word ); > } <snip> > static int getword2(char *buffer, int max) > { > int i, ch; <snip> > return ch; > } getword2 is unlikely to every return 0. It returns either EOF or the last character read. I don't think that s you. You want it to return an indication that there is, or is not, a word to be processed. <snip> > 1.) it does not discard the words containing anything else than > letters. Rather it discards everything else and read the letters. I simply > want to discard the *whole* word if it contains anything else than 26 > letters of English. See the last input where I input your name with junk > between CB and Falconer and it read them ![]() I doubt anyone will write this for you. It is a rather specific input routine and you will just have to work out a way to do it yourself. Do you plan using pseudo-code before starting to write the C? You will need to, I think, because such an input routine is quite complex. -- Ben. |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
> .... snip ... > > CB^%~!~%!++))::"?<Falconer > ----------> CB > ----------> Falconer > > [arnuld@raj C]$ > > you see the output. It has 3 problems: > > 1.) it does not discard the words containing anything else than > letters. Rather it discards everything else and read the letters. > I simply want to discard the *whole* word if it contains anything > else than 26 letters of English. See the last input where I input > your name with junk between CB and Falconer and it read them ![]() No. Your own demo shows that it reads and discards them. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com ** |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
>> CBFalconer wrote: > >> Try this. To generate EOF press ctl-D at line beginning. >> >> /* Get the next word consisting of alpha chars */ >> /* Return the terminating character (or EOF) */ >> /* Downshift the acquired word */ >> static int nextword(FILE *f, char *buffer, int max) >> { >> ...SNIP... > > one more nit, why use static int instead of int as return value ? The return value is int, not static int. The static applies to the function. If you read your C text you will see that it makes the function local to the source file in which it occurs. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section. ** Posted from http://www.teranews.com ** |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
> On Wed, 07 May 2008 12:35:35 -0400, CBFalconer wrote:
> Try this. To generate EOF press ctl-D at line beginning. > ... SNIP... since I do not have any FILE* so I changed it a little bit: int main( void ) { char word[MAX]; while( getword2( word, MAX ) ) { printf( "----------> %s\n", word ); } return 0; } static int getword2(char *buffer, int max) { int i, ch; while ( (!isalpha(ch = getchar())) && (ch != EOF) ) { continue; } if (EOF != ch) { i = 0; --max; do { if( i < max ) { buffer[i++] = ch; } } while ( isalpha(ch = getchar()) ); buffer[i] = '\0'; /* terminate string */ } return ch; } ================ OUTPUT ====================== [arnuld@raj C]$ gcc -ansi -pedantic -Wall -Wextra test.c test.c:125: warning: 'getword3' defined but not used [arnuld@raj C]$ ./a.out likethis ----------> likethis and about ----------> and ----------> about pppppppppppppppppllllllllllllllllllqqqqqqqqqqqqqq ----------> pppppppppppppppppllllllllllll like2 ----------> like lik678uyt ----------> lik ----------> uyt ----------> uyt ----------> uyt ----------> uyt ----------> uyt ----------> uyt ----------> uyt CB^%~!~%!++))::"?<Falconer ----------> CB ----------> Falconer [arnuld@raj C]$ you see the output. It has 3 problems: 1.) it does not discard the words containing anything else than letters. Rather it discards everything else and read the letters. I simply want to discard the *whole* word if it contains anything else than 26 letters of English. See the last input where I input your name with junk between CB and Falconer and it read them ![]() 2.) Ctrl-D does not do any exit but prints the last word it read ![]() 3.) thats good point, it discards the letters beyond MAX length ![]() -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
> On Wed, 07 May 2008 12:35:35 -0400, CBFalconer wrote:
> Try this. To generate EOF press ctl-D at line beginning. > > /* Get the next word consisting of alpha chars */ > /* Return the terminating character (or EOF) */ > /* Downshift the acquired word */ > static int nextword(FILE *f, char *buffer, int max) > { > ...SNIP... one more nit, why use static int instead of int as return value ? -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
> On Wed, 07 May 2008 10:58:41 +0100, Ben Bacarisse wrote:
> Be careful with your counts. Most people would say that a 30 > character words needs a 31 character array to store it. I'd say > your code accepts words up to and including 29 characters. oh.. I even forgot this fact. I changed it to 30 + 1 > This is underspecified. At least in one sense, if "anything else > beyond" has been discarded, how can there be any more input? Maybe > you want to throw away any more input on that line? yes, exactly > You can't change the Ctrl-D behaviour without resorting to some > serious OS-specific code. You may need a screen library like ncurses > if you go much further. I will accept it. -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
look "arnuld" Your clock is in the future! Please fix the clock of your machine. -- jacob navia jacob at jacob point remcomp point fr logiciels/informatique http://www.cs.virginia.edu/~lcc-win32 |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
arnuld wrote:
>> On Fri, 09 May 2008 10:20:33 +0200, jacob navia wrote: > >> look "arnuld" >> >> Your clock is in the future! >> >> Please fix the clock of your machine. > > oh.. NO.. not again ... > > > actually, it changes every time the machine boots, so I have to change it > back to normal time at every boot. I have tried changing the cell on the > motherboard but it still gives problems. > > > > You are 1 day in the future. This will destroy any makefiles build processes, and many other things in your system. It is a serious problem. -- jacob navia jacob at jacob point remcomp point fr logiciels/informatique http://www.cs.virginia.edu/~lcc-win32 |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On 9 May 2008 at 11:33, jacob navia wrote:
> You are 1 day in the future. This will destroy any makefiles build > processes, and many other things in your system. It is a serious > problem. Not necessarily - as long as his clock consistently tells the wrong time, he'll be OK. Problems can arise when you're using make with source files stored on an NFS mount, say - then the time make uses is the current time on your machine, while the timestamps of the files are set by the time on the NFS server. This can lead to annoying synchronization issues... |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
jacob navia <jacob@nospam.com> writes:
> arnuld wrote: >>> On Fri, 09 May 2008 10:20:33 +0200, jacob navia wrote: >> >>> look "arnuld" >>> >>> Your clock is in the future! >>> >>> Please fix the clock of your machine. >> >> oh.. NO.. not again ... >> >> >> actually, it changes every time the machine boots, so I have to change it >> back to normal time at every boot. I have tried changing the cell on the >> motherboard but it still gives problems. >> >> >> >> > > You are 1 day in the future. This will destroy any makefiles build > processes, and many other things in your system. It is a serious > problem. No because all his files are relativey timed. |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
> On Thu, 08 May 2008 11:45:24 +0100, Ben Bacarisse wrote:
> Neither you nor I are in doubt about what the function does -- I was > just asking that you be careful in your comments. For example, the > above remark is again vague: > > (a) the function may read many more than 30 characters; > (b) it does not read the '\0'; > (c) it may store up to 30 chars; > (d) the result may be a string as long as 29. > > Lots of errors can come from readers believing a program's incorrect > comments or from misunderstanding an ambiguous comment. I was just > suggesting that you take care when writing them. that was a nice advice. That is my mistake that I ignored this thing. Thanks ![]() -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
On Sat, 10 May 2008 00:08:14 +0500, arnuld <sunrise@see.sigs.invalid>
wrote: >> On Thu, 08 May 2008 11:54:31 +0100, Ben Bacarisse wrote: > > >> I doubt anyone will write this for you. It is a rather specific input >> routine and you will just have to work out a way to do it yourself. >> Do you plan using pseudo-code before starting to write the C? You >> will need to, I think, because such an input routine is quite >> complex. > >yes, it is complex *only* in C, I guess: > >I can discard the words containing anything else than characters: > > >/* version 1.4 */ > >int getword( char *word, int max ) >{ > int c, in_word; > char *w, *w_begin; > > w_begin = word; > w = word; > in_word = 0; > > while( isspace( c = getchar() )) > { > continue; > } > > > if( isalpha( c )) > { > *w++ = c; > } > > for( ; ( (c = getchar()) != EOF ) && --max ; ++w ) > { > if( isalpha(c) ) > { > in_word = 1; > *w = c; > } > else if( c == EOF || isspace( c ) ) > { > *w = '\0'; > in_word = 0; > return 1; > } > else > { > if( in_word ) > { > while( w != w_begin ) > { > *w-- = '\b'; > } > *w-- = '\b'; The -- here invokes undefined behavior. You are not allowed to point before the array that is passed to getword (if you originally pass the start of the array). > } > } > } > > > > *w = '\0'; And you are now storing data in memory through a wild pointer, more UB. If you fix things so this stores a '\0' at the beginning of the array, all the '\b' characters become irrelevant. > > return word[0]; Your stream is left pointing at the character following the non-alpha. Input of "ab cd9ef gh" would return words ab, '\0', ef, and gh. Do you really want that ef? >} >============= OUTPUT ============== >[arnuld@raj C]$ gcc -ansi -pedantic -Wall -Wextra getword.c >[arnuld@raj C]$ ./a.out >Ben9 >----------> >9Ben There is nothing in the code you showed that reorders the data. >----------> Ben >Be9n >----------> n >[arnuld@raj C]$ > > > >now only 2 things have remained: > >1.) it does not discard the whole-word if the non-character comes as 1st >element or within the word like 9Ben or Be9n but it will discard Ben9 >completely. So it is juts a half-implementation yet. Why even return when you find an unacceptable word. > > >2.) as usual, does not discard characters more than 30 . More than 30 should be treated the same as non-alpha, simply unacceptable. In both cases, continue reading (but not storing) until you reach the end of the word. > > >any ideas on that ? Remove del for email |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
> On Thu, 08 May 2008 11:54:31 +0100, Ben Bacarisse wrote:
> I doubt anyone will write this for you. It is a rather specific input > routine and you will just have to work out a way to do it yourself. > Do you plan using pseudo-code before starting to write the C? You > will need to, I think, because such an input routine is quite > complex. yes, it is complex *only* in C, I guess: I can discard the words containing anything else than characters: /* version 1.4 */ int getword( char *word, int max ) { int c, in_word; char *w, *w_begin; w_begin = word; w = word; in_word = 0; while( isspace( c = getchar() )) { continue; } if( isalpha( c )) { *w++ = c; } for( ; ( (c = getchar()) != EOF ) && --max ; ++w ) { if( isalpha(c) ) { in_word = 1; *w = c; } else if( c == EOF || isspace( c ) ) { *w = '\0'; in_word = 0; return 1; } else { if( in_word ) { while( w != w_begin ) { *w-- = '\b'; } *w-- = '\b'; } } } *w = '\0'; return word[0]; } ============= OUTPUT ============== [arnuld@raj C]$ gcc -ansi -pedantic -Wall -Wextra getword.c [arnuld@raj C]$ ./a.out Ben9 ----------> 9Ben ----------> Ben Be9n ----------> n [arnuld@raj C]$ now only 2 things have remained: 1.) it does not discard the whole-word if the non-character comes as 1st element or within the word like 9Ben or Be9n but it will discard Ben9 completely. So it is juts a half-implementation yet. 2.) as usual, does not discard characters more than 30 . any ideas on that ? -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
|
|
#25 |
|
Messages: n/a
Hébergeur: |
> On Fri, 09 May 2008 10:20:33 +0200, jacob navia wrote:
> look "arnuld" > > Your clock is in the future! > > Please fix the clock of your machine. oh.. NO.. not again ... actually, it changes every time the machine boots, so I have to change it back to normal time at every boot. I have tried changing the cell on the motherboard but it still gives problems. -- http://lispmachine.wordpress.com/ my email ID is @ the above blog. just check the "About Myself" page ![]() |
|
![]() |
| Outils de la discussion | |
|
|