尝试计算 C 中的单词时 EOF 没有终止
EOF not terminating when trying to count words in C
我正在阅读 K&R,其中一个代码计算字数。我决定尝试制作我自己的代码版本,但是使用我当前的代码,EOF(Ctrl+D
因为我在 Linux)不工作。
#include <stdio.h>
int main(void) {
int c, wc = 0;
while((c = getchar()) != EOF) {
while(c != ' ' && c != '\t' && c != '\n') {
wc++;
}
}
printf("%d", wc);
return 0;
}
我必须将 getchar()
添加到内部 while
循环中。
#include <stdio.h>
int main(void) {
int c, wc = 0;
while((c = getchar()) != EOF) {
while((c = getchar()) != ' ' && c != '\t' && c != '\n');
wc++;
}
printf("%d\n", wc);
return 0;
}
while((c = getchar()) != EOF) {
while(c != ' ' && c != '\t' && c != '\n') {
wc++;
}
}
当您第一次按下一个键时,内部 while 循环会触发并且永远不会退出,除非第一个键是条件中的一个。
因此,如果您按下 'A',内部 while 循环将永远持续下去。
您需要将 while
替换为 if
。并以 wc
仅在遇到或其他指定字符时才递增的方式修改条件,并且将执行 getchar()
以获取下一个字符。
下面的例子更接近于计算字数:
#include <stdio.h>
int main(void) {
int c, wc = 0;
int sep = 1;
while((c = getchar()) != EOF) {
if (c != ' ' && c != '\t' && c != '\n') {
if ( sep ){
wc++;
sep = 0;
}
}
else
sep = 1;
}
printf("%d", wc);
return 0;
}
我知道我在作弊,但这个例子展示了高级函数如何使程序更清晰。 scanf
的 %s
转换为我们进行分词。该示例使用 *
赋值抑制字符,它避免了为我们实际上不想知道的任意长单词提供 space 的需要。
#include <stdio.h>
int wordcount = 0;
int main(void) {
while(scanf("%*s") != EOF)
{
wordcount++;
}
printf("%d\n", wordcount);
return 0;
}
如果我必须自己滚动它,我会编写子例程。看看 main
看起来多干净!
#include <stdio.h>
/** @return 1 if c is whitespace, else 0. */
static int isWhite(int c);
/** When this function returns, c is either EOF or non-whitespace.
@return c
*/
static int readWhite();
/** When this function returns, c is either EOF or whitespace.
@return c
*/
static int readWord();
int main(void) {
int wordcount = 0;
while(readWhite() != EOF)
{
wordcount++;
readWord();
}
printf("%d\n", wordcount);
}
//////////////////////////////////////////////////////
static int isWhite(int c)
{
return c == '\n' || c == '\t' || c == ' ';
}
//////////////////////////////////////////////////////
static int readWord()
{
int c;
while((c = getchar()) != EOF && !isWhite(c))
{
; // this statement intentionally left blank
}
return c;
}
//////////////////////////////////////////////////////
static int readWhite()
{
int c;
while((c = getchar()) != EOF && isWhite(c))
{
; // this statement intentionally left blank
}
return c;
}
我正在阅读 K&R,其中一个代码计算字数。我决定尝试制作我自己的代码版本,但是使用我当前的代码,EOF(Ctrl+D
因为我在 Linux)不工作。
#include <stdio.h>
int main(void) {
int c, wc = 0;
while((c = getchar()) != EOF) {
while(c != ' ' && c != '\t' && c != '\n') {
wc++;
}
}
printf("%d", wc);
return 0;
}
我必须将 getchar()
添加到内部 while
循环中。
#include <stdio.h>
int main(void) {
int c, wc = 0;
while((c = getchar()) != EOF) {
while((c = getchar()) != ' ' && c != '\t' && c != '\n');
wc++;
}
printf("%d\n", wc);
return 0;
}
while((c = getchar()) != EOF) {
while(c != ' ' && c != '\t' && c != '\n') {
wc++;
}
}
当您第一次按下一个键时,内部 while 循环会触发并且永远不会退出,除非第一个键是条件中的一个。
因此,如果您按下 'A',内部 while 循环将永远持续下去。
您需要将 while
替换为 if
。并以 wc
仅在遇到或其他指定字符时才递增的方式修改条件,并且将执行 getchar()
以获取下一个字符。
下面的例子更接近于计算字数:
#include <stdio.h>
int main(void) {
int c, wc = 0;
int sep = 1;
while((c = getchar()) != EOF) {
if (c != ' ' && c != '\t' && c != '\n') {
if ( sep ){
wc++;
sep = 0;
}
}
else
sep = 1;
}
printf("%d", wc);
return 0;
}
我知道我在作弊,但这个例子展示了高级函数如何使程序更清晰。 scanf
的 %s
转换为我们进行分词。该示例使用 *
赋值抑制字符,它避免了为我们实际上不想知道的任意长单词提供 space 的需要。
#include <stdio.h>
int wordcount = 0;
int main(void) {
while(scanf("%*s") != EOF)
{
wordcount++;
}
printf("%d\n", wordcount);
return 0;
}
如果我必须自己滚动它,我会编写子例程。看看 main
看起来多干净!
#include <stdio.h>
/** @return 1 if c is whitespace, else 0. */
static int isWhite(int c);
/** When this function returns, c is either EOF or non-whitespace.
@return c
*/
static int readWhite();
/** When this function returns, c is either EOF or whitespace.
@return c
*/
static int readWord();
int main(void) {
int wordcount = 0;
while(readWhite() != EOF)
{
wordcount++;
readWord();
}
printf("%d\n", wordcount);
}
//////////////////////////////////////////////////////
static int isWhite(int c)
{
return c == '\n' || c == '\t' || c == ' ';
}
//////////////////////////////////////////////////////
static int readWord()
{
int c;
while((c = getchar()) != EOF && !isWhite(c))
{
; // this statement intentionally left blank
}
return c;
}
//////////////////////////////////////////////////////
static int readWhite()
{
int c;
while((c = getchar()) != EOF && isWhite(c))
{
; // this statement intentionally left blank
}
return c;
}