我希望函数在到达新行时打印0但是它不起作用但是从文件中获取每个单词都可以正常工作。快速回应将不胜感激。
输入文件中的数据如下所示:
blossom flower
bewilder confound confuse perplex
dwell live reside
代码:
int getWord(FILE * in, char str[]){
int ch;
int i = 0;
while(!isalpha(ch = getc(in)) && ch != EOF);
if(ch == EOF) return -1;
str[i++] = tolower(ch);
while(isalpha(ch = fgetc(in)) && ch != EOF){
if(i < MAX_WORD)
str[i++] = tolower(ch);
}
if(ch == '\n') return 0;
str[i] = '\0';
return 1;
}
答案 0 :(得分:3)
我的问题仍然没有得到解答 - 我只是想知道是什么导致它
return 0
。
由于:
当您下次调用该函数时,它会在第一个循环中读取LF并忽略它,因为它不是字母。
简洁地说,您的代码确实识别换行符 - 至少在Linux上。
#include <stdio.h>
#include <ctype.h>
enum { MAX_WORD = 50 };
static
int getWord(FILE *in, char str[])
{
int ch;
int i = 0;
while (!isalpha(ch = getc(in)) && ch != EOF)
;
if (ch == EOF)
return -1;
str[i++] = tolower(ch);
while (isalpha(ch = fgetc(in)) && ch != EOF)
{
if (i < MAX_WORD)
str[i++] = tolower(ch);
}
if (ch == '\n')
return 0;
str[i] = '\0'; // Bug; should be before the if
return 1;
}
int main(void)
{
char buffer[MAX_WORD];
int rc;
while ((rc = getWord(stdin, buffer)) >= 0)
printf("Got: %d (%s)\n", rc, buffer);
return 0;
}
给定输入文件:
blossom flower
bewilder confound confuse perplex
dwell live reside
程序产生输出:
Got: 1 (blossom)
Got: 0 (flowerm)
Got: 1 (bewilder)
Got: 1 (confound)
Got: 1 (confuse)
Got: 0 (perplex)
Got: 1 (dwell)
Got: 1 (live)
Got: 0 (residex)
请注意,当您读取换行符(返回0时)并且当前单词比前一个单词短时,您会在单词中留下杂散的字符。如果行上的最后一个单词比任何先前的单词长,并且堆栈足够混乱,则可能会出现不良行为。您可以通过在if
条件之前移动空终止来修复该错误。然后输出:
Got: 1 (blossom)
Got: 0 (flower)
Got: 1 (bewilder)
Got: 1 (confound)
Got: 1 (confuse)
Got: 0 (perplex)
Got: 1 (dwell)
Got: 1 (live)
Got: 0 (reside)
请注意,在Windows上,如果程序读取'\r'
(CRLF行结尾的CR部分),则会跳过零返回,因为终止该单词的字符为'\r'
,在下一次调用函数时,第一个循环会跳过'\n'
。
请注意,指示平台(Unix vs Windows)将有助于澄清问题并更快地得到答案。
请注意,当我创建DOS(Windows)格式文件data.dos
,并使用相同(错误修复)二进制文件(在Ubuntu 14.04衍生版上运行)读取时,输出为:
Got: 1 (blossom)
Got: 1 (flower)
Got: 1 (bewilder)
Got: 1 (confound)
Got: 1 (confuse)
Got: 1 (perplex)
Got: 1 (dwell)
Got: 1 (live)
Got: 1 (reside)
这完全对应于&CR; CR终止该单词,第一个循环跳过换行符&#39;场景。您还可以通过在战略位置添加打印语句来进行调试:
#include <stdio.h>
#include <ctype.h>
enum { MAX_WORD = 50 };
static
int getWord(FILE *in, char str[])
{
int ch;
int i = 0;
while (!isalpha(ch = getc(in)) && ch != EOF)
{
if (ch == '\n') printf("Got-1 '\\n'\n");
else if (ch == '\r') printf("Got-1 '\\r'\n");
else printf("Got-1 '%c'\n", ch);
}
if (ch == EOF)
return -1;
str[i++] = tolower(ch);
while (isalpha(ch = fgetc(in)) && ch != EOF)
{
if (i < MAX_WORD)
str[i++] = tolower(ch);
}
if (ch == '\n') printf("Got-2 '\\n'\n");
else if (ch == '\r') printf("Got-2 '\\r'\n");
else printf("Got-2 '%c'\n", ch);
str[i] = '\0';
if (ch == '\n')
return 0;
return 1;
}
int main(void)
{
char buffer[MAX_WORD];
int rc;
while ((rc = getWord(stdin, buffer)) >= 0)
printf("Got: %d (%s)\n", rc, buffer);
return 0;
}
在Unix文件中,输出现在是:
Got-2 ' '
Got: 1 (blossom)
Got-2 '\n'
Got: 0 (flower)
Got-2 ' '
Got: 1 (bewilder)
Got-2 ' '
Got: 1 (confound)
Got-2 ' '
Got: 1 (confuse)
Got-2 '\n'
Got: 0 (perplex)
Got-2 ' '
Got: 1 (dwell)
Got-2 ' '
Got: 1 (live)
Got-2 '\n'
Got: 0 (reside)
使用Windows文件:
Got-2 ' '
Got: 1 (blossom)
Got-2 '\r'
Got: 1 (flower)
Got-1 '\n'
Got-2 ' '
Got: 1 (bewilder)
Got-2 ' '
Got: 1 (confound)
Got-2 ' '
Got: 1 (confuse)
Got-2 '\r'
Got: 1 (perplex)
Got-1 '\n'
Got-2 ' '
Got: 1 (dwell)
Got-2 ' '
Got: 1 (live)
Got-2 '\r'
Got: 1 (reside)
Got-1 '\n'
请注意,Unix / Linux不会特别处理CRLF组合;它们只是输入流中的两个相邻字符。