打印从文本文件中读取的每个单词的第 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 个字符(' ') 也作为分隔符。

等等

我的建议是,使用以下算法重写您的代码。

  1. 分配足够长的缓冲区以容纳文件中的完整
  2. 打开文件,检查是否成功。
  3. 使用fgets()

    将整行读入缓冲区

    3.1。如果 fgets() return NULL,您 很可能 已到达文件末尾。结束。

    3.2。否则,继续下一步。

  4. 使用 strtok() 进行标记,使用 space ' ' 作为分隔符。检查 returned 标记是否为 NULL。

    4.1。如果 token 为 NULL,转到第 3 步。

    4.2。如果令牌不为 NULL,则继续下一步。

  5. 检查 returned 标记的 strlen()(即 word)。如果大于4,打印token的index 4。 (请记住,c 中的数组索引是基于 0 的)。

  6. 继续第 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 只是一个无限循环(条件定义为 true1),在 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:

  1. Loop (outer loop) until end-of-file (EOF).
  2. 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