Reputation: 3
I wanted to find the 5th letter from every word after reading from the text file. I do not know where I am wrong.
After entering the file path, I am getting a pop up window reading
read.c
has stopped working.
The code:
#include<stdio.h>
#include<conio.h>
int main(void){
char fname[30];
char ch[]={'\0'};
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;
}
Upvotes: 0
Views: 493
Reputation: 871
I edited your code because of these reasons:
You don't need to use char
array at all, since you're only checking for letters and you can count the letters in every word of the file (which can be checked using spaces) and print when your count reaches 4
(since we start at 0
).
Since gets()
has no overflow protection, fgets()
is more preferred.
fgets(fname, sizeof(fname), stdin);
Another point is you can simplify your do-while
loop into one while
loop with the condition of breaking if reaching EOF
, since your do-while
is simply an infinite loop (with condition defined as true
or 1
) that breaks at EOF
(which is checked in a separate if
inside the infinite do-while
).
while (!feof)
An alternative to char
array is to loop until a space ' '
or newline '\n'
is found.
I also removed the else
from if (fp==0)
to avoid too many indents.
ctype.h
to check if the 5th letter is really a letter using 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.
Applying those edits to your code,
#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;
}
*Note: Words with less than 5 letters will not be included in the output, but you can specify a character or number to indicate that a word has less than 5 letters. (such as 0
, -1
)
sample read.txt
:
reading write love coder heart stack overflow
output:
enter file name with path
read.txt
iertkf
Upvotes: 1
Reputation: 134286
I wanted to find the 5th letter from every word
That's not something your code is doing now. It is wrong for various reasons, like
char ch[]={'\0'};
is an array with length 1. with unbound ch[i]
, you're overrunning the allocated memory creating undefined behaviour.gets()
is very dangerous, it can cause buffer overflow.getc()
reads character-by-character, not word-by-word, so you need to take care of space character (' '
) as a delimiter also.etc.
My suggestion, rewrite your code using the following algorithm.
Read a whole line to the buffer using fgets()
3.1. If fgets()
return NULL, you've most probably reached the end of file. End.
3.2. Otherwise, continue to next step.
Tokenize the line using strtok()
, using space ' '
as the delimiter. Check the returned token against NULL.
4.1. if token is NULL, go to step 3.
4.2. if token is not NULL, proceeded to next step .
Check strlen()
of the returned token (which is the word). if it is more than 4
, print the index 4 of the token. (Remember, array index in c
is 0
based).
Continue to step 4.
Upvotes: 5
Reputation: 1598
You can use following snippet. With this code you need to know Maximum length of line. This code prints 5th character on each line on each word if its length is 5 or more.. Hope this work for you.
#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] = '\0';
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;
}
Upvotes: 2