Search string in a file in c - c

I am trying to write a program that can search a string in a file (called student.txt). I want my program to print the word if it finds the same word in the file, but its showing error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int num =0;
char word[2000];
char *string[50];
FILE *in_file = fopen("student.txt", "r");
//FILE *out_file = fopen("output.txt", "w");
if (in_file == NULL)
{
printf("Error file missing\n");
exit(-1);
}
while(student[0]!= '0')
{
printf("please enter a word(enter 0 to end)\n");
scanf("%s", student);
while(!feof(in_file))
{
fscanf(in_file,"%s", string);
if(!strcmp(string, student))==0//if match found
num++;
}
printf("we found the word %s in the file %d times\n",word,num );
num = 0;
}
return 0;
}

Added a sample code in its simplest form. Take care of any corner cases.
If you are searching a string "to". And file content is :
<tom took two tomatoes to make a curry> .
The output would come as 5. But in actual there is only one word "to".
Code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
int num =0;
char word[2000];
char string[50];
char student[100] = {0};
while(student[0]!= '0')
{
FILE *in_file = fopen("student.txt", "r");
if (in_file == NULL)
{
printf("Error file missing\n");
exit(-1);
}
printf("please enter a word(enter 0 to end)\n");
scanf("%s", student);
while ( fscanf(in_file,"%s", string) == 1)
{
//Add a for loop till strstr(string, student) does-not returns null.
if(strstr(string, student)!=0) {//if match found
num++;
}
}
printf("we found the word %s in the file %d times\n",student,num );
num = 0;
fclose(in_file);
}
return 0;
}
As rightly said by my fellow colleagues we need to have one more loop to traverse for any further instance of same word in the same line.
Note: In case if you want the word "to" only to be counted, make sure to check the "string - 1" and "string + 1" character for all the possible word delimiters like space, comma, full stop, newline, Exclamatory, ampersand, equals and any other possibilities. One simple way would be to use strtok which would tokenize the buffer into words based on delimiters specified in the argument. Checkout how to use strtok.
http://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm

You should read (create a function) words from the file. And by words I mean array of non-whitespace characters surrounded by whitespaces such as blank space (but don't record the white spaces in the words list). Then search through the word list (or through the words on the fly) to look for the required word.

Either use variable student in the last printf() line or place your matched text in variable word and also check your if condition.

Related

Get the user to enter a name but using file stream *fp

I am a beginner in c so I have a problem with get the user to input last name, a comma & then first name. However it will pass to the function call
int get_name(FILE *fp)
in my main function. I have a problem either if I have to use the arguments parameters.
Example, main (int argc, char *argv[])) or just main (void))
and from what I have been searching so far, FILE*fp cannot get the user to enter from stdin it only use to open the file(?) BUT I am required to get the user to input from keyboard and pass to the function. I have written some codes. but they don't seem to work but I am going to put down on here the one I am sure that I need a few changes most.
#define LINESIZE1024
int main(void){
FILE *fp;
char line[LINESIZE];
char first;
char last;
char comma;
while(1){
if(!fgets(line,LINESIZE,stdin)){
clearerr(stdin);
break;
}
if(fp = (sscanf(line,"%s %s %s",&last,&comma,&first)==3))
get_name(fp);
if(get_last_first(fp)== -1)
break;
printf("Please enter first name a comma and then last name");
}
BUT I got an error saying I can't use pass it from pointer to an integer. and many MORE but I accidentally closed my concolse and all the errors that appeared while I was trying to fix are gone. So please give me some ideas.
What about seconde code
while(1){
if(!fgets(line,LINESIZE,fp)){
clearerr(stdin);
break;
}
if(sscanf(line,"%s %s %s",last,comma,first)==3)
get_last_first(fp);
return 0;
}
It gave me errors too. fp,last,first,comma used uninitialized in this function
OK so I think I have fixed the previous problem now. However it doesn't print the name back if the name is given correctly. Here is my fixed main code.
int main(void){
FILE *fp = stdin;
char line[LINESIZE];
char first[16];
char last[16];
while(1){
if(!fgets(line,LINESIZE,stdin)){
clearerr(stdin);
break;
}
if(sscanf(line,"%s ,%s",last,first)==2)
if(get_name(fp)==2)
printf("Your name is: %s %s\n", first, last);
}
return 0;
}
here is my function.
int get_name(FILE *fp){
char line[LINESIZE];
char last[16], first[16];
int n;
/* returns -1 if the input is not in the correct format
or the name is not valid */
if(fgets(line, LINESIZE, fp) == NULL) {
return -1;
}
/* returns 0 on EOF */
if((n = sscanf(line, " %[a-zA-Z-] , %[a-zA-Z-]", last, first)) == EOF) {
return 0;
}
/* prints the name if it's valid */
if((n = sscanf(line, " %[a-zA-Z-] , %[a-zA-Z-]", last, first)) == 2) {
return 2;
}
return 1;
}
I thank you people so much for taking time to read and help me. Please don't be mean :)
Seems that you are making it more complicated than needed. Don't call fgets and scanf in main. Only do that in the function get_name.
It can be something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINESIZE 1024
int get_name(FILE *fp)
{
char line[LINESIZE];
char* t;
if(!fgets(line, LINESIZE,fp))
{
printf("Error reading input\n");
return 0;
}
t = strstr(line, ",");
if (t)
{
*t = '\0';
++t;
printf("First: %s - Last: %s\n", line, t);
return 2;
}
printf("Illegal input\n");
return 0;
}
int main(int argc, char **argv)
{
get_name(stdin);
return 0;
}
If you later decide that you want to read from a file, you can reuse the function get_name without changing it at all. All you need is to change main. Like:
int main(int argc, char **argv)
{
FILE* f = fopen("test.txt", "r");
if (f)
{
get_name(f);
fclose(f);
}
else
{
printf("Open file failed\n");
}
return 0;
}
If you want to read from the keyboard, read from stdin or use scanf, which internally reads from stdin. If you want to read from a file instead, use FILE *fp, but don't forget to open the file and check if it was successful (you'll find lots of tutorials for this).
Further, when reading in strings, you need an array of characters, not a single one. Note further, that scanf can already deal with formats like "everything that is not a ',' then a ',' then a string. Note that format "[^,]" means "any character except a ',':
So you could adapt the code as follows:
#define LINESIZE 1024
int main(void){
char line[LINESIZE];
char first[LINESIZE];
char last[LINESIZE];
while(fgets(line,LINESIZE,stdin)) {
if(sscanf(line,"%[^,],%s",last,first)==2) {
printf("Read in %s ... %s\n",last,first);
}
else {
printf("Please enter first name a comma and then last name");
}
}
return 0;
}
And if your professor is picky concerning the "use FILE*", you could write:
FILE *fp = stdin;
...
while(fgets(line,LINESIZE,fp)) {
...

How can I take each word from an array alone and test if it fits specific conditions? (C)

I am trying to create a program that reads a sentence from a text file and then prints only the words that do NOT start with a vowel.
So I wrote a program that reads the text file and copies the sentence into an array. Now, I'm struggling with actually testing each word in the array for whether it fits the condition (not starting with a vowel) or not.
So far I can only do that by using the strtok function and using the spaces as delimeters, but that also eliminates the spaces from the sentence, which isn't the desired result.
For example, if the text file contains the following sentence:
An apple a day keeps the doctor away.
The output will be:
daykeepsthedoctor
While the desired output is:
day keeps the doctor
Here's my program:
#include <stdio.h>
#include <string.h>
int vowelwords();
int main()
{
vowelwords();
return 0;
}
int vowelwords()
{
FILE *fPtr;
char text[50];
fPtr = fopen("TEXT1.txt","r"); //to open file
if (fPtr == NULL) //Catch error in fopen function
{
printf("Error in opening file\n");
return 1;
}
fgets(text, 50, fPtr);
fclose(fPtr);
char *c;
c = strtok(text," ");
while(c!= NULL)
{
if(c[0]=='a'||c[0]=='A'||c[0]=='e'||c[0]=='E'||c[0]=='u'||
c[0]=='U'||c[0]=='i'||c[0]=='I'||c[0]=='o'||c[0]=='O')
{
}
else
{
printf("%s", c);
}
c = strtok(NULL," ");
}
printf("\n");
}
While printing leave a space in printf in function int vowelwords() -
printf("%s ", c);
^ leave a space

Program to count number of times a character appear in file(case insensitive)

executed this code in an online editor.but always getting File 'test.txt' has 0 instances of letter 'r'.what to do??File 'test.txt' has 99 instances of letter'r'.This is the expected output.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
int main()
{
FILE *fptr;
int d=0;
char c;
char ch,ck;
char b[100];
printf("Enter the file name\n");
scanf("%19s",b);
fptr=fopen(b,"r");
printf("Enter the character to be counted\n");
scanf(" %c",&c);
c=toupper(c);
if(fptr==NULL)
{
exit(-1);
}
while((ck=fgetc(fptr))!=EOF)
{
ch=toupper(ck);
if(c==ch||c==ck)
++d;
}
fclose(fptr);
printf("File '%s' has %d instances of letter '%c'.",b,d,c);
return(0);
}
Problems:
ck should be an int, not a char as #alk has pointed out because fgetc returns an int, not a char.
As per the title, you want a case insensitive comparision. Your code does not do that. The solution is that this:
if(c==ch||c==ck)
needs to be
if(c == ch || (tolower(c)) == ck) /* Compare upper with upper, lower with lower */
I tested it. It works fine. I can't detect your problem without you providing the test file it fails on. As far as I am concerned, it does what it is supposed to do - it counts the number of times specified character appears (case-insensitive) in specified file. Here's your prettified version of your code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen */
#include <ctype.h>
#define MAX_FILENAME_LENGTH 100
int main(int argc, char **argv) {
/* Variables */
FILE *file = NULL;
int count = 0, file_char;
char target_char, filename[MAX_FILENAME_LENGTH];
/* Getting filename */
printf("Enter the file name: ");
fgets(filename, MAX_FILENAME_LENGTH, stdin);
/* Removing newline at the end of input */
size_t filename_len = strlen(filename);
if(filename_len > 0 && filename[filename_len - 1] == '\n') {
filename[filename_len - 1] = '\0'; }
/* Opening file */
file = fopen(filename, "r");
if(file == NULL) exit(EXIT_FAILURE);
/* Getting character to count */
printf("Enter the character to be counted: ");
scanf(" %c", &target_char);
target_char = toupper(target_char);
/* Counting characters */
while((file_char = fgetc(file)) != EOF) {
file_char = toupper(file_char);
if(target_char == file_char) ++count; }
/* Reporting finds */
printf("File '%s' has %d instances of letter '%c'.",
filename, count, target_char);
/* Exiting */
fclose(file);
return EXIT_SUCCESS; }

Word palindrome in C

My task is to find word palindromes in a text file and to NOT print them into results file. The results file should only contain all the spaces and words that are NOT palindromes. I've been working on this program for two solid weeks, but as I am a total newb in C, I can't simply imagine how to do this correctly. Also, I have to work in Linux environent, so I can't use commands like strrev() which would make my life a lot easier at this point...
Anyways, data file contains a lot of words in a lot of lines separated by quite a few spaces.
Here is the program that is working, but doesn't work with any spaces, because I don't know how to check them at the needed place.
#include <stdio.h>
#include <string.h>
const int CMAX = 1000;
const int Dydis = 256;
FILE *dataFile;
FILE *resFile;
void palindrome(char *linex);
int main(){
char duom[CMAX], res[CMAX], linex[Dydis];
printf("What's the name of data file? \n");
scanf("%s", duom);
dataFile=fopen(duom, "r");
if (dataFile==NULL){
printf ("Error opening data file \n");
return 0;
};
printf("What's the name of results file? \n");
scanf ("%s", res);
resFile=fopen(res, "w");
if (resFile==NULL){
printf ("Error opening results file \n");
return 0;
};
while (fgets(linex, sizeof(linex), dataFile)) {
palindrome(linex);
}
printf ("all done!");
fclose(dataFile);
fclose(resFile);
}
void palindrome(char *linex){
int i, wordlenght, j;
j = 0;
char *wordie;
const char space[2] = " ";
wordie = strtok(linex, space);
while ( wordie != NULL ) {
wordlenght = strlen(wordie);
if (wordie[j] == wordie[wordlenght-1]) {
for (i = 0; i < strlen(wordie); i++) {
if (wordie[i] == wordie[wordlenght-1]) {
if (i == strlen(wordie)-1) {
fprintf(resFile,"");
}
wordlenght--;
}
else {
fprintf(resFile,"%s", wordie);
break;
}
}
}
else {
fprintf(resFile,"%s", wordie);
}
wordie = strtok(NULL, space);
}
}
EDIT:
Code below works as following:
input file is read char by char
if char read isn't alphanumeric, then it is written to the output file
else, the whole word is read with fscanf
if word is not a palindrome, then write to the output file
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int is_pal(char* word) {
size_t len = strlen(word);
char* begin = word;
char* end = word + len - 1;
if (len == 1) {
return 1;
}
while (begin <= end) {
if (*begin != *end) {
return 0;
}
begin++;
end--;
}
return 1;
}
int main(void)
{
FILE* fin = fopen("pals.txt", "r");
if (fin == NULL) {
perror("fopen");
exit(1);
}
FILE* fout = fopen("out_pals.txt", "w");
if (fout == NULL) {
perror("fopen");
exit(1);
}
int ret;
char word[100];
while ((ret = fgetc(fin)) != EOF) {
if (!isalpha(ret)) {
fprintf(fout, "%c", ret);
}
else {
ungetc(ret, fin);
fscanf(fin, "%s", word);
if (!is_pal(word)) {
fprintf(fout, "%s", word);
}
}
}
fclose(fin);
fclose(fout);
return 0;
}
I've created file with following content:
cancer kajak anna sam truck
test1 abc abdcgf groove void
xyz annabelle ponton belowoleb thing
cooc ringnir
The output file :
cancer sam truck
test1 abc abdcgf groove void
xyz annabelle ponton thing
(line with two spaces)
As you can see, the number of spaces between words are the same as in the input file.
I've assumed that single word could have 100 chars maximum. If there would be longer words, reading with fscanf onto fixed-size buffer can be harmful.
Hints:
strtok() gives you a pointer to the start of delimited words but it does not
extract them or put them in their own string for you.
You need some logic to find the end of each word. The function
strlen() will tell you how many characters there are from the char*
that it gets until a null-character. If you give it a pointer to the start
of a word within a sentence it will give you the length from the start of the
word to the end of the sentence.
Breaking palindrome() into a function that loops over words in a line and a
function that returns whether or not a single word is a palindrome
may help.
Your for loop is checking each pair of letters twice. i only needs to scan over half
of the word length.
You only need a single if within palindrome(). I'm not sure why you have so many.
They're redundant.

Program that lets a user search a file for words

I'm attempting to create a program that lets the user enter words and then the program searches the file for the entered word. I believe what happens in my program however is that as I enter the words it doesn't start over at 0 of the char array I'm entering it into
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int num =0;
char word[2000];
char *string;
FILE *in_file = fopen("words.txt", "r");
//FILE *out_file = fopen("output.txt", "w");
if (in_file == NULL)
{
printf("Error file missing\n");
exit(-1);
}
while(word[0]!= '0')
{
printf("please enter a word(enter 0 to end)\n");
scanf("%s",word);
while(!feof(in_file))
{
fscanf(in_file,"%s",string);
if(!strcmp(string,word))//if match found
num++;
}
printf("we found the word %s in the file %d times\n",word,num );
num = 0;
}
return 0;
}
Can someone help me so that it rereads into the correct position? So that when it goes to compare the words it does so correctly?
You forgot to declare memory for char *string;. Your program tries to write with fscanf(in_file,"%s",string); in unreserved memory causing undefined behavior and then very likely a crash.
Replace char *string; with char string[ MAX_WORD_LENGTH ]
There are many other problems, for example your search might only work on the first try since you are reading the file every time and once you hit EOF you won't read any more. You should set the position indicator to the beginning of the file with fseek on every search.
fseek ( in_file, 0, SEEK_SET );
Also using strstr instead of strcmp might produce better results.

Resources