打印从文本文件中读取的每个单词的第 5 个字母
Print the 5th letter of each word read from a text file
我想从文本文件中读取每个单词的第 5 个字母。我不知道我哪里错了。
输入文件路径后,弹出 window 阅读
read.c
has stopped working.
代码:
#include<stdio.h>
#include<conio.h>
int main(void){
char fname[30];
char ch[]={'[=10=]'};
int i=0;
FILE *fp;
printf("enter file name with path\n");
gets(fname);
fp=fopen(fname,"r");
if(fp==0)
printf("file doesnot exist\n");
else{
printf("File read successfully\n");
do{
ch[i]=getc(fp);
if(feof(fp)){
printf("end of file");
break;
}
else if(ch[i]=='\n'){
putc(ch[4],stdout);
}
i++;
}while(1);
fclose(fp);
}
return 0;
}
I wanted to find the 5th letter from every word
这不是您的代码现在正在做的事情。由于各种原因,它是错误的,例如
char ch[]={'[=10=]'};
是一个长度为 1 的数组。使用未绑定的 ch[i]
,您将超出分配的内存,从而创建 undefined behaviour.
gets()
非常危险,会导致缓冲区溢出。
getc()
读取 个字符 ,而不是逐字读取,因此您需要注意 space 个字符(' '
) 也作为分隔符。
等等
我的建议是,使用以下算法重写您的代码。
- 分配足够长的缓冲区以容纳文件中的完整 行。
- 打开文件,检查是否成功。
使用fgets()
将整行读入缓冲区
3.1。如果 fgets()
return NULL,您 很可能 已到达文件末尾。结束。
3.2。否则,继续下一步。
使用 strtok()
对 行 进行标记,使用 space ' '
作为分隔符。检查 returned 标记是否为 NULL。
4.1。如果 token 为 NULL,转到第 3 步。
4.2。如果令牌不为 NULL,则继续下一步。
检查 returned 标记的 strlen()
(即 word)。如果大于4
,打印token的index 4。 (请记住,c
中的数组索引是基于 0
的)。
继续第 4 步。
您可以使用以下代码段。使用此代码,您需要知道 行的最大长度。此代码在 每个单词的每一行打印第 5 个字符,如果它的长度为 5 或更多。。希望这对你有用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 1000
int main()
{
char fname[30];
char myCurLine[MAX_LINE + 1];
char myCurWord[MAX_LINE + 1];
int index,loop;
FILE *fp;
printf("enter file name with path\n");
gets(fname);
fp=fopen(fname,"r");
if(fp==0)
printf("file doesnot exist\n");
else
{
printf("File read successfully\n");
do
{
if(fgets(myCurLine,MAX_LINE,fp) != NULL)
{
index = 0;
for(loop = 0;loop < MAX_LINE; loop++)
{
myCurWord[index] = myCurLine[loop];
index++;
if((myCurLine[loop] == ' ') || (myCurLine[loop] == '\n'))
{
myCurWord[index] = '[=10=]';
index = 0;
if(strlen(myCurWord) > 4)
{
putchar(myCurWord[4]);
}
index = 0;
if(myCurLine[loop] == '\n')
break;
}
}
}
if(feof(fp))
{
break;
}
}while(1);
fclose(fp);
}
return 0;
}
由于这些原因,我编辑了您的代码:
你根本不需要使用 char
数组,因为你只检查字母,你可以计算文件中每个单词的字母(可以是使用 spaces 检查)并在计数达到 4
时打印(因为我们从 0
开始)。
由于gets()
没有溢出保护,fgets()
更受青睐
fgets(fname, sizeof(fname), stdin);
另一点是,您可以将 do-while
循环简化为一个 while
循环,条件是达到 EOF
时中断,因为您的 do-while
只是一个无限循环(条件定义为 true
或 1
),在 EOF
处中断(在无限 [=19= 内部的单独 if
中检查]).
while (!feof)
char
数组的替代方法是循环直到找到 space ' '
或换行符 '\n'
。
我还从 if (fp==0)
中删除了 else
以避免缩进过多。
- 我还添加了
ctype.h
来检查第 5 个字母是否真的是使用 isalpha()
的字母。
This is how the word's 5th letter search works:
- Loop (outer loop) until end-of-file (
EOF
).
In each iteration of outer loop, loop (inner loop) until a space ' '
or newline '\n'
is found.
- If the counter in inner loop reaches
4
(which means 5th letter is reached),
- print the current letter,
- reset counter to zero,
- then break the inner loop.
将这些编辑应用于您的代码,
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
int main(void){
char fname[30];
char ch; // changed from array to single char
int i=0;
FILE *fp;
printf("enter file name with path\n");
fgets(fname, sizeof(fname), stdin); // changed from gets()
// removes the \n from the input, or else the file won't be located
// I never encountered a file with newlines in its name.
strtok(fname, "\n");
fp=fopen(fname,"r");
// if file open failed,
// it tells the user that file doesn't exits,
// then ends the program
if (!fp) {
printf("file does not exist\n");
return -1;
}
// loops until end-of-file
while (!feof(fp))
// loops until space or newline or when 5th letter is found
for (i = 0; (ch=getc(fp)) != ' ' && ch != '\n'; i++)
// if 5th character is reached and it is a letter
if (i == 4 && isalpha(ch)) {
putc(ch ,stdout);
// resets letter counter, ends the loop
i = 0;
break;
}
fclose(fp);
return 0;
}
*注意:少于5个字母的单词不会被输出,但您可以指定一个字符或数字来表示一个单词少于5个字母. (例如0
、-1
)
样本read.txt
:
reading write love
coder heart
stack overflow
输出:
enter file name with path
read.txt
iertkf
我想从文本文件中读取每个单词的第 5 个字母。我不知道我哪里错了。
输入文件路径后,弹出 window 阅读
read.c
has stopped working.
代码:
#include<stdio.h>
#include<conio.h>
int main(void){
char fname[30];
char ch[]={'[=10=]'};
int i=0;
FILE *fp;
printf("enter file name with path\n");
gets(fname);
fp=fopen(fname,"r");
if(fp==0)
printf("file doesnot exist\n");
else{
printf("File read successfully\n");
do{
ch[i]=getc(fp);
if(feof(fp)){
printf("end of file");
break;
}
else if(ch[i]=='\n'){
putc(ch[4],stdout);
}
i++;
}while(1);
fclose(fp);
}
return 0;
}
I wanted to find the 5th letter from every word
这不是您的代码现在正在做的事情。由于各种原因,它是错误的,例如
char ch[]={'[=10=]'};
是一个长度为 1 的数组。使用未绑定的ch[i]
,您将超出分配的内存,从而创建 undefined behaviour.gets()
非常危险,会导致缓冲区溢出。getc()
读取 个字符 ,而不是逐字读取,因此您需要注意 space 个字符(' '
) 也作为分隔符。
等等
我的建议是,使用以下算法重写您的代码。
- 分配足够长的缓冲区以容纳文件中的完整 行。
- 打开文件,检查是否成功。
使用
将整行读入缓冲区fgets()
3.1。如果
fgets()
return NULL,您 很可能 已到达文件末尾。结束。3.2。否则,继续下一步。
使用
strtok()
对 行 进行标记,使用 space' '
作为分隔符。检查 returned 标记是否为 NULL。4.1。如果 token 为 NULL,转到第 3 步。
4.2。如果令牌不为 NULL,则继续下一步。
检查 returned 标记的
strlen()
(即 word)。如果大于4
,打印token的index 4。 (请记住,c
中的数组索引是基于0
的)。继续第 4 步。
您可以使用以下代码段。使用此代码,您需要知道 行的最大长度。此代码在 每个单词的每一行打印第 5 个字符,如果它的长度为 5 或更多。。希望这对你有用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 1000
int main()
{
char fname[30];
char myCurLine[MAX_LINE + 1];
char myCurWord[MAX_LINE + 1];
int index,loop;
FILE *fp;
printf("enter file name with path\n");
gets(fname);
fp=fopen(fname,"r");
if(fp==0)
printf("file doesnot exist\n");
else
{
printf("File read successfully\n");
do
{
if(fgets(myCurLine,MAX_LINE,fp) != NULL)
{
index = 0;
for(loop = 0;loop < MAX_LINE; loop++)
{
myCurWord[index] = myCurLine[loop];
index++;
if((myCurLine[loop] == ' ') || (myCurLine[loop] == '\n'))
{
myCurWord[index] = '[=10=]';
index = 0;
if(strlen(myCurWord) > 4)
{
putchar(myCurWord[4]);
}
index = 0;
if(myCurLine[loop] == '\n')
break;
}
}
}
if(feof(fp))
{
break;
}
}while(1);
fclose(fp);
}
return 0;
}
由于这些原因,我编辑了您的代码:
你根本不需要使用
char
数组,因为你只检查字母,你可以计算文件中每个单词的字母(可以是使用 spaces 检查)并在计数达到4
时打印(因为我们从0
开始)。由于
gets()
没有溢出保护,fgets()
更受青睐fgets(fname, sizeof(fname), stdin);
另一点是,您可以将
do-while
循环简化为一个while
循环,条件是达到EOF
时中断,因为您的do-while
只是一个无限循环(条件定义为true
或1
),在EOF
处中断(在无限 [=19= 内部的单独if
中检查]).while (!feof)
char
数组的替代方法是循环直到找到 space' '
或换行符'\n'
。我还从
if (fp==0)
中删除了else
以避免缩进过多。- 我还添加了
ctype.h
来检查第 5 个字母是否真的是使用isalpha()
的字母。
This is how the word's 5th letter search works:
- Loop (outer loop) until end-of-file (
EOF
).In each iteration of outer loop, loop (inner loop) until a space
' '
or newline'\n'
is found.
- If the counter in inner loop reaches
4
(which means 5th letter is reached),
- print the current letter,
- reset counter to zero,
- then break the inner loop.
将这些编辑应用于您的代码,
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
int main(void){
char fname[30];
char ch; // changed from array to single char
int i=0;
FILE *fp;
printf("enter file name with path\n");
fgets(fname, sizeof(fname), stdin); // changed from gets()
// removes the \n from the input, or else the file won't be located
// I never encountered a file with newlines in its name.
strtok(fname, "\n");
fp=fopen(fname,"r");
// if file open failed,
// it tells the user that file doesn't exits,
// then ends the program
if (!fp) {
printf("file does not exist\n");
return -1;
}
// loops until end-of-file
while (!feof(fp))
// loops until space or newline or when 5th letter is found
for (i = 0; (ch=getc(fp)) != ' ' && ch != '\n'; i++)
// if 5th character is reached and it is a letter
if (i == 4 && isalpha(ch)) {
putc(ch ,stdout);
// resets letter counter, ends the loop
i = 0;
break;
}
fclose(fp);
return 0;
}
*注意:少于5个字母的单词不会被输出,但您可以指定一个字符或数字来表示一个单词少于5个字母. (例如0
、-1
)
样本read.txt
:
reading write love coder heart stack overflow
输出:
enter file name with path
read.txt
iertkf