I have program that replaces a word in a file with another one, but in the new file the lines are all written as one line, not in different lines and paragraphs as required.
I tried adding '\n' at the end of each line I am reading from the original file, but it is not working.
This is my code:
int main() {
FILE *f1, *f2;
char word[MAX], fname[MAX];
char s[MAX], replace[MAX];
char temp[] = "temp.txt", *p1, *p2;
printf("Enter your input file name:");
fgets(fname, MAX, stdin);
fname[strlen(fname) - 1] = '\0';
scanf("%s", word);
scanf("%s", replace);
f1 = fopen(fname, "r");
if (!f1) {
printf("Unable to open the input file!!\n");
return 0;
}
f2 = fopen(temp, "w");
if (!f2) {
printf("Unable to open temporary file!!\n");
return 0;
}
while (fscanf(f1,"%[^\n]%*c", &s) != EOF) {
printf("%s",s); //I wanted to see what happens when I'm reading from the file. Previously I added at the end of string s the char '\n' but it didnt work
if (strstr(s, word)) {
p2 = s;
while (p1 = strstr(p2, word)) {
while (p2 != p1) {
fputc(*p2, f2);
p2++;
}
p1 = p1 + strlen(word);
fprintf(f2, "%s", replace);
p2 = p1;
}
while (*p2 != '\0') {
fputc(*p2, f2);
p2++;
}
} else {
fputs(s, f2);
}
}
fclose(f1);
fclose(f2);
remove(fname);
rename(temp, fname);
return 0;
}
The simple reason is that you are not outputting a newline to the file. The fscanf doesn't include the newline in s (because you specifically omit it with [^\n], which means "characters other than newline").
If you just add putc('\n', f2); at the very end of the outer while loop, it works fine.
Alternatively, you could just read with fgets, which does include the newline in the string. An added benefit is that fgets forces you to specify the maximum length as an argument, while guarding against excessive line length with fscanf requires you to put the length in the format string itself.
(Note that the printf("%s", s); has no effect on what goes into the file, since it outputs to stdout.)
You should use fgets() to read from the input file instead of fscanf(f1,"%[^\n]%*c", &s) for multiple reasons:
you do not give fscanf() to maximum number of characters to store into s: any sufficiently long line in the input file will cause undefined behavior.
you read the line from f1 and explicitly skip the newline, this explains why the newline never gets written to f2.
fscanf() will fail on an empty line because there are no characters different from \n to read into s, s is unmodified and gets handled like the previous line (or undefined behavior on the first line), and the loop iterates at the same spot in the input file, effectively stuck forever writing to f2 to no avail...
Here is a corrected and simplified version:
#include <stdio.h>
#include <string.h>
#define MAX 100
int main() {
FILE *f1, *f2;
char word[MAX], fname[MAX];
char s[MAX], replace[MAX];
char temp[] = "temp.txt";
char *p1, *p2;
printf("Enter your input file name: ");
if (!fgets(fname, sizeof fname, stdin))
return 1;
fname[strcspn(fname, "\n")] = '\0'; /* strip the newline if present */
printf("Enter the word to search: ");
if (scanf("%99s", word) != 1)
return 1;
printf("Enter the replacement word: ");
if (scanf("%99s", replace) != 1)
return 1;
f1 = fopen(fname, "r");
if (!f1) {
fprintf(stderr, "Unable to open the input file %s\n", fname);
return 1;
}
f2 = fopen(temp, "w");
if (!f2) {
fprintf(stderr, "Unable to open temporary file %s\n", temp);
return 1;
}
while (fgets(s, sizeof s, f1)) {
p1 = s;
while ((p2 = strstr(p1, word)) != NULL) {
while (p1 < p2) {
fputc(*p1++, f2);
}
fputs(replace, f2);
p1 += strlen(word);
}
fputs(p1, f2);
}
fclose(f1);
fclose(f2);
remove(fname);
rename(temp, fname);
return 0;
}
Note however that if the input file has very long lines with matches spanning multiple chunks read by fgets(), these matches will be missed by the program.
Here is a different approach to avoid this problem:
#include <stdio.h>
#include <string.h>
#define MAX 100
int main() {
FILE *f1, *f2;
char fname[MAX], word[MAX], replace[MAX];
char temp[] = "temp.txt";
char *p1 *p2;
int c;
printf("Enter your input file name: ");
if (!fgets(fname, sizeof fname, stdin))
return 1;
fname[strcspn(fname, "\n")] = '\0'; /* strip the newline if present */
printf("Enter the word to search: ");
if (scanf("%99s", word) != 1)
return 1;
printf("Enter the replacement word: ");
if (scanf("%99s", replace) != 1)
return 1;
f1 = fopen(fname, "r");
if (!f1) {
fprintf(stderr, "Unable to open the input file %s\n", fname);
return 1;
}
f2 = fopen(temp, "w");
if (!f2) {
fprintf(stderr, "Unable to open temporary file %s\n", temp);
return 1;
}
p2 = word;
while ((c = getc(f1)) != EOF) {
if (c != '\0' && *p2 == (char)c) {
p2++;
if (*p2 == '\0') {
fputs(replace, f2);
p2 = word;
}
} else {
for (p1 = word; p1 < p2;) {
putc(*p1++, f2);
/* find potential match for special cases: find aab in aaab */
if (!memcmp(word, p1, p2 - p1) && word[p2 - p1] == (char)c)
p2 = word + (p2 - p1) + 1;
p1 = word;
break;
}
}
if (p1 == p2) {
putc(c, f2);
}
}
}
/* flush potential partial match at end of file */
for (p1 = word; p1 < p2; p1++) {
putc(*p1, f2);
}
fclose(f1);
fclose(f2);
remove(fname);
rename(temp, fname);
return 0;
}
a first error is to give the address of s to fscanf, fscanf(f1,"%[^\n]%*c",&s) must be fscanf(f1,"%[^\n]%*c",s)
anyway, just replace your fscanf by a simple fgets and all will be ok, you will not loose \n
P.S. if you cannot be sure MAX is not enough to handle lines you have to manage the case a line is cut in several at read, and may be the word to replace in cut because of that. There are several ways to do that.
So you want modify words in a file, but keep all whitespace as is? Then it is important to read and write the whitespace. Using read-functions that skips whitespace won't help you much.
Here is a generic version of a read-modify loop. Fixing bugs and extending it to a compete program, including error handling, is left as exercise to the reader
while (1)
{
// Read the next character
int ch = fgetc(infile);
if (ch == EOF)
break; // read error or eof
if (isspace(ch))
{
// The character was a whitespace, so we copy it to the outputstream
int err = fputc(ch, outfile);
if (err == EOF)
break; // error
}
else
{
// The next character was not a whitespace, so we put it back in the
// inputstream for scanf to find it
ungetc(ch, instream);
char word[64]; // Just assume for simplicity that no words are longer
// than 63 character.
// Read the next string, making sure we don't read more than the buffer
// can handle. A robust program should do something useful if words are
// actually longer than 63 characters
int len = fscanf(infile, "%63s", word);
if (len == EOF)
break; // error (should not happen since there is guarantied to be
// one non-whitespace character in the stream)
char mod_word[64];
modify_word(mod_word, word);
int err = fputs(mod_word, outfile);
if (err == EOF)
break; // error
}
}
// Check for read-write errors
if (ferror(infile))
perror("Failure reading from input file");
if (ferror(outfile))
perror("Failure writing to output file");
Related
I'm trying to copy words from one file to another, but the words must begin with the given letter. It's working but doesn't copy every word that matches.
#include <stdio.h>
int main() {
FILE *f = fopen("words.txt", "r");
FILE *f2 = fopen("words_copy.txt", "a+");
char usr;
printf("enter letter: ");
scanf("%c", &usr);
char buffer[255];
char ch, ch2;
while ((ch = fgetc(f)) != EOF) {
ch2 = fgetc(f);
if (ch2 == usr && ch == '\n') {
fputc(ch2, f2);
fgets(buffer, sizeof(buffer), f);
fputs(buffer, f2);
}
}
return 0;
}
Words.txt contains:
adorable aesthetic alluring angelic appealing arresting attractive
blooming charismatic charming cherubic chocolate-box classy contagious
cute dazzling debonair decorative delectable delicate distinguished
enchanting enticing eye-catching glamorous glossy good-looking
gorgeous infectious lovely lush magnetic magnificent majestic melting
mesmerizing noble picturesque poetic prepossessing shimmering striking
stunning winsome
every word is in next line,
when I'm running the program and giving the letter m words_copy.txt contains only:
magnificent melting
How to fix to copy every word with matching letter?
The test in the loop is incorrect: you check the first letter after a newline and output the line if there is a match. With this logic:
you cannot match the first word in the file
you only match words starting with usr
and the word following a match is ignored
Furthermore, you ch and ch2 should be defined with type int to match EOF reliably, you should test for fopen failure and close the files after use.
You should use a simpler approach:
read a word
test if it contains the letter
output the word if it matches
Here is a modified version:
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char usr;
char buffer[256];
int ch = 0;
size_t pos;
FILE *f = fopen("words.txt", "r");
if (f == NULL) {
fprintf(stderr, "cannot open words.txt: %s\n", strerror(errno));
return 1;
}
FILE *f2 = fopen("words_copy.txt", "a+");
if (f2 == NULL) {
fprintf(stderr, "cannot open words_copy.txt: %s\n", strerror(errno));
fclose(f);
return 1;
}
printf("enter letter: ");
if (scanf(" %c", &usr) != 1) {
fprintf(stderr, "missing input\n");
fclose(f);
fclose(f2);
return 1;
}
while (ch != EOF) {
pos = 0;
/* read a word, stop at whitespace and end of file */
while ((ch = fgetc(f)) != EOF && !isspace(ch)) {
if (pos + 1 < sizeof(buffer))
buffer[pos++] = (char)ch;
}
buffer[pos] = '\0';
/* test for a match */
if (strchr(buffer, usr)) {
/* output matching word */
fprintf(f2, "%s\n", buffer);
}
}
fclose(f);
fclose(f2);
return 0;
}
Im trying to read a text file into an array of structs, but when trying to print the array, the struct is empty. The printing function works fine and I think the problem is in getRawData.
struct student
{
char ID[MAXID + 1];
char f_name[FIRST_NAME_LENGTH + 1];
char s_name[LAST_NAME_LENGTH + 1];
int points[MAXROUNDS];
};
//main//
case 'W':
if(save(array, len) == 0);
{
printf("Data saved.\n");
}
break;
case 'O':
if(getRawData(array, len));
{
printf("File read.\n");
}
break;
int save(struct student *h, int num_students)
{
char name[20];
printf("Enter file name: " );
scanf("%s", name); // Read in filename
FILE *output = fopen(name, "w"); // open the file to write
if (!output) {
return -1; // error
}
for (int i = 0; i < num_students; ++i)
{
fprintf(output, "%s %s %s \n", h[i].f_name, h[i].s_name, h[i].ID);
for(int j = 0; j < MAXROUNDS; j++)
{
fprintf(output, "%d\n", h[i].points[j]);
}
printf("Information of student %s %s (%s) written into file %s\n", h[i].s_name, h[i].f_name, h[i].ID, name);
}
fclose(output); // close
return 0;
}
int getRawData(struct student *records)
{
int i;
int nmemb; // amount of structs
char name[20];
printf("Name of the file to be opened: \n");
scanf("%s", name);
FILE *outtput = fopen(name, "r");
int ch=0;
int lines=0;
if (outtput == NULL);
return 0;
lines++;
while(!feof(outtput))
{
ch = fgetc(outtput);
if(ch == '\n')
{
lines++;
}
}
nmemb = lines / 7;
for(i = 0; i < nmemb; i++) {
fscanf(outtput, "%s %s %s", records[i].f_name, records[i].s_name, records[i].ID);
for(int j = 0; j < MAXROUNDS; j++)
{
fscanf(outtput, "%d\n", &records[i].points[j]);
}
}
printf("%d", lines);
return i;
}
So my goal is to get the data from the file and write it over whatever there is stored in the struct array. I would appreciate some help as I have been working on this for way too long.
Look at this code in getRawData(), first you are reading file to identify total number of lines:
while(!feof(outtput))
{
ch = fgetc(outtput);
if(ch == '\n')
.....
.....
due to this the file stream pointer pointing to EOF and after this, in the for loop, you are doing:
for(i = 0; i < nmemb; i++) {
fscanf(outtput, "%s %s %s", records[i].f_name, records[i].s_name, records[i].ID);
.....
.....
Here, the fscanf() must be returning the EOF because there is nothing remain to read from stream file. You should check the return value of fscanf() while reading file.
You should reset the pointer to start of file before reading it again. You can use either rewind(ptr) or fseek(fptr, 0, SEEK_SET). Below is a sample program to show you what is happening in your code and how the solution works:
#include <stdio.h>
int main (void) {
int ch;
int lines = 0;
char str[100];
FILE *fptr = fopen ("file.txt", "r");
if (fptr == NULL) {
fprintf (stderr, "Failed to open file");
return -1;
}
while (!feof(fptr)) {
ch = fgetc (fptr);
if(ch == '\n') {
lines++;
}
}
printf ("Number of lines in file: %d\n", lines);
printf ("ch : %d\n", ch);
printf ("Now try to read file using fscanf()\n");
ch = fscanf (fptr, "%s", str);
printf ("fscanf() return value, ch : %d\n", ch);
printf ("Resetting the file pointer to the start of file\n");
rewind (fptr); // This will reset the pointer to the start of file
printf ("Reading file..\n");
while ((ch = fscanf (fptr, "%s", str)) == 1) {
printf ("%s", str);
}
printf ("\nch : %d\n", ch);
fclose (fptr);
return 0;
}
The content of file reading in the above program:
Hello Vilho..
How are you!
Output:
Number of lines in file: 2
ch : -1
Now try to read file using fscanf()
fscanf() return value, ch : -1
Resetting the file pointer to the start of file
Reading file..
HelloVilho..Howareyou!
ch : -1
Here you can see, the first ch : -1 indicate that the file pointer is at EOF and if you try to read you will get EOF because there is nothing left to read. After resetting file pointer, you can see fscanf() is able to read file.
You should not use while (!feof(file)). Check this.
** Updated 26/10 -> First of all thank you all for you help, I am getting closer now, I need more work and studying but I really appreciate you are helping me a lot :-)
Still don't know why the first "rain" word in the input.txt file is not getting the positive output from strcmp, and from the cmd I can see the "<" bracket don't appear except for the LAST line which is the line that works.
Also checked the highlighted response from Removing trailing newline character from fgets() input
and even if I change the code to the following:
while( fgets (line, sizeof line, fp)!=NULL ) {
/* remove \n from at the end of the str buffer*/
char * pos;
/*
if ((pos = strchr(line, '\n')) != NULL)
*pos = '\0';
*/
line[strcspn(line, "\n")] = 0;
I get the same result as if I use the if block instead. Maybe I'm getting extra \0 which might be the case. Anyone has a link where I can read about the delimiters I just used, or a nice reference of a debugger, etc. ... which I will have a look as soon as I come here? Thank you so much in advance!
read5.c version: Now from that input.txt file, it had an extra space on the last "rain" word, I removed the space, and it was able to find and get that last word compare as a true result, running in the strcmp if block. but that was the only string that was a true positive result from that if block.
on the cmd I can see:
$./read5 input.txt rain output.txt sun
>Maria
>rain
>manel
>Bla bla
<rain>
Found it! rain
On the output.txt it becomes:
Maria
rain
manel
Bla bla
sun
read5.c
#include <stdio.h>
#include <string.h>
/**
* Compile program:
* gcc read3.c -o read3
*
*/
int main (int argc, char **argv) {
FILE *fp, *fo;
char *compare, *replace;
char line[246];
if (argc <= 4){
printf(">Missing arguments on the command line.\n");
printf(">Be sure you run the program as\n\"./read3 input.txt compare outout.txt replace\"\n\n");
}
/* opening file for reading */
fp = fopen(argv[1] , "r");
if(fp == NULL){
perror("Error opening input file");
return 1;
}
compare = argv[2];
fo = fopen(argv[3], "w");
if(fo == NULL){
perror("Error opening output file");
return 1; //TODO check if: return 1 because it was expected, right?
}
replace = argv[4];
/*
printf(); made to test version 2
//printf("We are going to compare %s\n", compare);
//printf("We are going to replace it with %s\n", replace);
*/
while( fgets (line, sizeof line, fp)!=NULL ) {
/* remove \n from at the end of the str buffer*/
char * pos;
if ((pos = strchr(line, '\n')) != NULL)
*pos = '\0';
/* print str enclosed in <> so we can see what str actually contains */
//printf("Inside the loop, got the string: %s\n", line);
//printing the strings with defined delimiters
printf("<%s>\n", line);
if(strcmp(compare, line) == 0){
printf("Found it! %s \n", line);
fprintf(fo, "%s\n", replace);
}
else{
fprintf(fo, "%s\n", line);
}
}
fclose(fp);
fclose(fo);
return 0;
}
First question with no edits: 25/10
I need to make a program that is run like this:
./read2 input.txt rain output.txt sun
It reads the input.txt, searches for rain string and if finds it, replaces it with sun string and outputs all the text from input.txt with the replacements to the output.txt.
But with the code that I have so far, the strcmp is not comparing the strings I want, maybe it has the extra space that I get on the command line, I don't know... for now what is doing is copying everything from input.txt to output.txt... It's running the else block always...
Read2.c:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
FILE *fp, *fo;
char str[60];
//char* token;
/* opening file for reading */
fp = fopen(argv[1], "r");
char *compare = argv[2];
fo = fopen(argv[3], "w+");
char *replace = argv[4];
if (fp == NULL) {
perror("Error opening file");
return(-1);
}
//printf("We are going to compare %s\n", compare);
//printf("We are going to replace it with %s\n", replace);
while (fgets(str, 60, fp) != NULL) {
/* writing content to stdout */
//Take the \n out
//token = strtok(str, "\n");
printf("Inside the loop, got the string: %s\n", str);
if (strcmp(compare, str) == 0) {
//puts(str);
printf("Found it! %s \n", str);
fprintf(fo, "%s", replace);
} else {
fprintf(fo, "%s", str);
}
}
fclose(fp);
return(0);
}
input.txt:
Maria
rain
manel
Bla bla
rain
Ouput.txt becomes exactly as input.txt and before it was empty, so the code is working, except the if block that tests with strcmp.
The problem is the \n at the end of the str buffer. fgets adds the \n at end end of the line it reads, you need to get rid of it before comparing.
This is what you need:
while (fgets(str, 60, fp) != NULL) {
/* remove \n from at the end of the str buffer*/
char *pos;
if ((pos = strchr(str, '\n')) != NULL)
*pos = '\0';
/* print str enclosed in <> so we can see what str actually contains */
printf("Inside the loop, got the string: <%s>\n", str);
if (strcmp(compare, str) == 0) {
printf("Found it! %s\n", str);
fprintf(fo, "%s\n", replace);
}
else {
fprintf(fo, "%s\n", str);
}
}
Look at the comments in the code for explanations.
read.c
#include <stdio.h>
#include <string.h>
/**
* How to compile program:
* gcc read.c -o read
*
* How to run the program:
* .> ./read input.txt rainy output.txt sunny
* (On Windows MinGW compiler, simply:
* .> read input.txt rainy output.txt sunny - without ./)
*
*/
int main (int argc, char **argv) {
FILE *fp, *fo;
char *compare, *replace;
char line[246];
if (argc <= 4){
printf(">Missing arguments on the command line.\n");
printf(">Be sure you run the program as\n\"./read input.txt compare outout.txt replace\"\n\n");
}
/* Opening files for reading */
fp = fopen(argv[1] , "r");
if(fp == NULL){
perror("Error opening input file");
return 1;
}
compare = argv[2];
fo = fopen(argv[3], "w");
if(fo == NULL){
perror("Error opening output file");
return 1;
}
replace = argv[4];
while( fgets (line, (sizeof line), fp)!=NULL ) {
line[strcspn(line, "\n")] = 0;
if(strcmp(compare, line) == 0){
printf("Found it! %s \n", line);
fprintf(fo, "%s\n", replace);
}
else{
fprintf(fo, "%s\n", line);
}
}
fclose(fp);
fclose(fo);
return 0;
}
/*
Important info
strcspn ::
Locate first occurrence of character in string,
after locating the first occurrence of \n, replaces it by 0.
Sources::
https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221
Used to debug:
.>printf("1st: Reads input.txt, removes '\\n' from fgets, and prints it \n");
.>printf("2nd: Compares each line with 'rainy' \n");
.>printf("<%s>\n", line);
*/
input.txt
cloudy
rainy
chilly
rainy
rainy
Your approach fails because the lines read from the input file contain a trailing newline '\n' that makes the comparison return non zero.
You can strip the newline before comparing with the search string.
Note that there are other problems:
you should verify that enough command line arguments have been passed by testing argc > 4.
there is no need to open the output file in update mode "w+", "w" is simpler and better.
60 bytes is a bit small for the line array, limiting the longest line handled correctly to 58 bytes.
Here is an improved version:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
FILE *fp, *fo;
char *compare, *replace;
char line[256];
if (argc <= 4) {
printf("missing command line arguments\n");
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
perror("Error opening input file");
return 1;
}
compare = argv[2];
fo = fopen(argv[3], "w");
if (fo == NULL) {
perror("Error opening output file");
return 1;
}
replace = argv[4];
while (fgets(line, sizeof line, fp) != NULL) {
line[strcspn(line, "\n")] = '\0';
if (strcmp(line, compare) == 0) {
printf("fount it!);
fprintf(fo, "%s\n", replace);
} else {
fprintf(fo, "%s\n", line);
}
}
fclose(fp);
fclose(fo);
return 0;
}
Note that long lines will be broken into chunks that fit in the line array, so there may be false positives with the above naive approach.
You can remove this limitation completely with this inner loop:
int c;
int pos = 0;
int cmplen = strlen(compare);
for (;;) {
c = getc(fp);
if (c == '\n' || c == EOF) {
if (pos == cmplen) {
fprintf(fo, "%s", replace);
} else
if (pos > 0) {
fprintf(fo, "%*s", pos, compare);
}
pos = 0;
if (c == EOF)
break;
} else {
if (pos >= 0) {
if (compare[pos] == (char)c) {
pos++;
continue;
}
if (pos > 0) {
fprintf(fo, "%*s", pos, compare);
}
pos = -1;
}
}
putc(c, fo);
}
This program attempts to save the contents of a text file into a character variable array. It is then supposed to use my_getline() to print the contents of the character array. I've tested and see that the contents are in fact getting saved into char *text but I can't figure out how to print the contents of char *text using my_getline(). my_getline is a function we wrote in class that I need to use in this program. When I attempt to call it in the way that was taught, it 1 is printed to terminal but then the terminal just waits and nothing else is printed. Any guidance would be appreciated. Also, let me know if I'm missing any information that would help.
/* Include the standard input/output and string libraries */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Define the maximum lines allowed in an input text and NEWLINE for getline funct. */
#define MAXPATTERN 15
#define MAXFILENAMELENGTH 15
#define NEWLINE '\n'
/* function prototypes */
void my_getline(char text[]);
int find_string(char text[], char pattern[], int length_text, int length_pattern);
int main()
{
FILE *fp;
long lSize;
char *text;
char fileName[MAXFILENAMELENGTH], pattern[MAXPATTERN];
char c;
int length_text, length_pattern, j, lineNumber = 1;
printf("Enter file name: ");
scanf("%s", fileName);
fp = fopen(fileName, "r");
if (fp == NULL)
{
printf("fopen failed.\n");
return(-1);
}
fseek(fp, 0L, SEEK_END);
lSize = ftell(fp);
rewind(fp);
/* allocate memory for all of text file */
text = calloc(1, lSize + 2);
if(!text)
{
fclose(fp);
fputs("memory allocs fails", stderr);
exit(1);
}
/* copy the file into text */
if(1 != fread(text, lSize, 1, fp))
{
fclose(fp);
free(text);
fputs("Entire read fails", stderr);
exit(1);
}
text[lSize + 1] = '\0';
printf("%s has been copied.\n", fileName);
rewind(fp);
printf("%d ", lineNumber);
for (j = 0; (j = getchar()) != '\0'; j++)
{
my_getline(text);
printf("%d %s\n", j+1, text);
}
printf("Enter the pattern you would like to search for: ");
scanf("%s", pattern);
printf("\nYou have chosen to search for: %s\n", pattern);
fclose(fp);
free(text);
return(0);
}
void my_getline(char text[])
{
int i = 0;
while ((text[i] = getchar()) != NEWLINE)
++i;
text[i] = '\0';
}
Your function is causing a system hang because you're calling getchar(), which returns the next character from the standard input. Is this really what you want?
At this point, your program is expecting input from the user. Try typing in the console windows and pressing to see it coming back from the "hang"
It is most likely causing an infinite loop because you are not checking whether you have reached EOF.
void my_getline(char text[])
{
int i = 0;
int c;
while ( (c = getchar()) != NEWLINE && c != EOF )
text[i++] = c;
text[i] = '\0';
}
I want to write code were the user is asked to write the name of a file. Then I want to analyze the file's content for a symbol, let's say 'e'.
My problem is that I don't know how to start analyzing the file the correct way so that the content can be checked.
int main() {
char c[1000], file_name[1000];
int i;
int s = 0;
FILE *fp;
printf("Enter the name of file you wish to see\n");
gets(file_name);
if ((fp = fopen(file_name, "r")) == NULL){
printf("Error! opening file");
exit(1);
}
if (fp) {
while (fscanf(fp, "%s", c) != EOF) {
printf("%s", c);
}
fclose(fp);
for (i = 0; c[i] != '\0'; ++i) {
puts(c);
if (c[i] == 'e') {
++s;
}
}
printf("\nWhite spaces: %d", s);
_getche();
return 0;
}
}
char line[512]; /*To fetch a line from file maximum of 512 char*/
rewind(fp);
memset(line,0,sizeof(line)); /*Initialize to NULL*/
while ( fgets(line, 512, fp ) && fp !=EOF)
{
/*Suppose u want to analyze string "WELL_DONE" in this fetched line.*/
if(strstr(line,"WELL_DONE")!=NULL)
{
printf("\nFOUND KEYWOD!!\n");
}
memset(line,0,sizeof(line)); /*Initialize to null to fetch again*/
}
If its just a symbol you're looking for, or a char, you can simply use getc() :
int c;
....
if (fp) {
while ((c = getc(fp)) != EOF) {
if (c == 'e') {
// Do what you need
}
}
Or, alternatively, if it's a word you're looking for, fscanf() will do the job:
int c;
char symb[100];
char symbToFind[] = "watever"; // This is the word you're looking for
....
while ((c = fscanf(fp, %s, symb)) != EOF) {
if (strcmp(symb, symbToFind) == 0) { // strcmp will compare every word in the file
// do whatever // to symbToFind
}
}
These alternatives will allow you to search every char or string in the file, without having to save them as an array.