Related
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");
I need to make a program that prompts the user for the name of two text files which will be read in and displayed on screen followed by their statistics, such as number of characters, words and lines. I've managed to get it all working apart from the statistics part. They don't seem to be counting up and I think it's something to do with the while statements that I've used. Any help would be great :)
code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main() {
// declaring variables
FILE *fp;
int charcount = 0, wordcount = 0, linecount = 0;
int character;
char first[50];
char second[50];
char ch[200];
// asking the user for the file names and scanning the names they enter as txt files
printf(" Enter the first file name: ");
scanf("%s", first);
strcat(first, ".txt");
printf(" Enter the second file name: ");
scanf("%s", second);
strcat(second, ".txt");
// opening the file stream
fp = fopen(first, "r");
// if the file cannot be reached, display error
if (fp == NULL) {
printf("File cannot be opened: %s\n", first);
return 0;
}
// reading and printing the file into the program
printf("\n---FIRST FILE---\n");
while (!feof(fp)) {
fgets(ch, 200, fp);
puts(ch);
}
// counting the characters, words and lines until the program is finished
while ((character = getc(fp)) != EOF) {
if (character == '-')
{
charcount++;
}
if (character == ' ')
{
wordcount++;
}
if (character == '\n')
{
linecount++;
}
}
// closing the stream
fclose(fp);
// printing the number of characters, words and lines
printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n\n", charcount, wordcount, linecount);
//---------SECOND FILE----------//
// opening the stream
fp = fopen(second, "r");
// reading and printing the file into the program
printf("\n---SECOND FILE---\n");
while (!feof(fp)) {
fgets(ch, 200, fp);
puts(ch);
}
// counting the characters, words and lines until the program is finished
while ((character = getc(fp)) != EOF) {
if (character == '-')
{
charcount++;
}
if (character == ' ')
{
wordcount++;
}
if (character == '\n')
{
linecount++;
}
}
// closing the stream
fclose(fp);
// printing the number of characters, words and lines
printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n", charcount, wordcount, linecount);
}
Imagine that you're using one of those text editors to open your file and moving the caret/cursor is the only way to navigate. Your first goal is to navigate through the whole content and display it. That's what the loop below does:
while(!feof(fp)){
fgets(ch, 200, fp);
puts(ch);
}
The !feof(fp) moved the cursor to the end of the file so you could read it all.
If you have to count chars then you need to navigate back to somewhere in your file. Since you want statistics from the whole txt, then you could simply use rewind(fp) or fseek(fp, 0, SEEK_SET) before your second loop to move the cursor back to the begin.
I recommed using fseek() because it will clear the end of file indicator.
Take a closer look here.
I finally got it to work, if anyone is interested the final code is here:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main() {
// declaring variables
FILE *fp;
int charcount = 0, wordcount = 0, linecount = 1;
int charcount2 = 0, wordcount2 = 0, linecount2 = 1;
int character;
char first[50];
char second[50];
char ch[200];
// asking the user for the file names and scanning the names they enter as txt files
printf(" Enter the first file name: ");
scanf("%s", first);
strcat(first, ".txt");
printf(" Enter the second file name: ");
scanf("%s", second);
strcat(second, ".txt");
// opening the file stream
fp = fopen(first, "r");
// if the file cannot be reached, display error
if (fp == NULL) {
printf("File cannot be opened: %s\n", first);
return 0;
}
// reading and printing the file into the program
printf("\n---FIRST FILE---\n");
while (!feof(fp)) {
fgets(ch, 200, fp);
fputs(ch, stdout);
}
// counting the characters, words and lines until the program is finished
fseek(fp, 0, SEEK_SET);
while ((character = fgetc(fp)) != EOF) {
if (character == EOF)
break;
{
charcount++;
}
if (character == ' ' || character == '.')
{
wordcount++;
}
if (character == '\n')
{
linecount++;
}
}
// closing the stream
fclose(fp);
// printing the number of characters, words and lines
printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n\n", charcount, wordcount, linecount);
//---------SECOND FILE----------//
// opening the stream
fp = fopen(second, "r");
// reading and printing the file into the program
printf("\n---SECOND FILE---\n");
while (!feof(fp)) {
fgets(ch, 200, fp);
fputs(ch, stdout);
}
// counting the characters, words and lines until the program is finished
fseek(fp, 0, SEEK_SET);
while ((character = getc(fp)) != EOF) {
if (character == EOF)
break;
{
charcount2++;
}
if (character == ' ' || character == '.')
{
wordcount2++;
}
if (character == '\n')
{
linecount2++;
}
}
// closing the stream
fclose(fp);
// printing the number of characters, words and lines
printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n", charcount2, wordcount2, linecount2);
}
counting sample
#include <stdio.h>
#include <ctype.h>
typedef struct statistics {
size_t charcount, wordcount, linecount;
} Statistics;
Statistics count_cwl(FILE *fp){
size_t c = 0, w = 0, l = 0;
int ch;
char prev = ' ';
while((ch = getc(fp)) != EOF){
++c;
if(isspace(prev) && !isspace(ch)){
++w;//need to delete punctuation marks ?
}
if(ch == '\n'){
++l;
}
prev = ch;
}
if(prev != '\n')//There is no newline at the end of the file
++l;
return (Statistics){ c, w, l};
}
int main(void) {
char filename[50] = "test.c";
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("File cannot be opened: %s\n", filename);
return -1;
}
Statistics stat = count_cwl(fp);
fclose(fp);
printf("\nCharacters: %zu\nWords: %zu\nLines: %zu\n", stat.charcount, stat.wordcount, stat.linecount);
}
I am writing a C program to convert all uppercase characters to lowercase and all lowercase to uppercase from a file.
I also want to count the characters read and the number of characters converted to uppercase and characters converted to lowercase.
I am able to convert the characters but unable to figure out how to count them.
Example;
Hello World!
Output;
hELLO wORLD!
Read 13 characters in total.
8 converted to uppercase.
2 converted to lowercase.
Here's my code;
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define INPUT_FILE "input.txt"
#define OUTPUT_FILE "output.txt"
int main()
{
FILE *inputFile = fopen(INPUT_FILE, "rt");
if (NULL == inputFile) {
printf("ERROR: cannot open the file: %s\n", INPUT_FILE);
return -1;
}
// 2. Open another file
FILE *outputFile = fopen(OUTPUT_FILE, "wt");
if (NULL == inputFile) {
printf("ERROR: cannot open the file: %s\n", OUTPUT_FILE);
return -1;
}
int c;
int ch;
int upper = 0;
int lower = 0;
int count = 0;
while (EOF != (c = fgetc(inputFile))) {
ch = islower(c)? toupper(c) : tolower(c);
fputc(ch, outputFile);
}
while (EOF != (c = fgetc(inputFile))) {
if (isupper(c))
{
upper++;
}
else if (islower(c))
{
lower++;
}
fputc(upper, outputFile);
fputc(lower, outputFile);
}
fclose(inputFile);
fclose(outputFile);
return 0;
}
Your main problem is that you are using 2 loops to read input file.
Your second loop should rewind the file before to start re-reading the file.
You can count and convert with a single loop.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define INPUT_FILE "input.txt"
#define OUTPUT_FILE "output.txt"
int main()
{
FILE *inputFile = fopen(INPUT_FILE, "rt");
if (NULL == inputFile) {
printf("ERROR: cannot open the file: %s\n", INPUT_FILE);
return -1;
}
// 2. Open another file
FILE *outputFile = fopen(OUTPUT_FILE, "w");
if (NULL == outputFile) {
printf("ERROR: cannot open the file: %s\n", OUTPUT_FILE);
return -1;
}
int ch;
int upper = 0;
int lower = 0;
int count = 0;
while (EOF != (ch = fgetc(inputFile)))
{
if (isalpha(ch))
{
if (islower(ch))
{
ch = toupper(ch);
upper++;
}
else
{
ch = tolower(ch);
lower++;
}
count++;
}
fputc(ch, outputFile);
}
fprintf(outputFile, "\nTotal: %d\nToUpper: %d\nToLower: %d\n", count, upper, lower);
fclose(inputFile);
fclose(outputFile);
return 0;
}
Take also note that you have to check if a read char is an alpha char before to convert the case, as the isalpha call inside the loop do.
Supposing that I have two files like this:
file1.txt
john
is
the new
guy
file2.txt
man
the old
is
rick
cat
dog
I'd like to compare first line from file1 with all the lines from file2 and verify if it exist. If not, go two the second line from file1 and compare it with all the lines from file2.. and so on until eof is reached by file1.
The output that I expect is:
john
the new
guy
How I thought this should be done:
read file1 and file2
create a function which returns the line number of each of them
take the first line from file1 and compare it to all the lines from file2
do this until all the lines from file1 are wasted
Now, I don't know what I'm doing wrong, but I don't get the result that I expect:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int countlines(char *filename)
{
int ch = 0, lines = 0;
FILE *fp = fopen(filename, "r");
if (fp == NULL)
return 0;
do {
ch = fgetc(fp);
if (ch == '\n')
lines++;
} while (ch != EOF);
if (ch != '\n' && lines != 0)
lines++;
fclose(fp);
return lines;
}
int main(int argc, char *argv[])
{
FILE *template_file = fopen(argv[1], "r");
FILE *data_file = fopen(argv[2], "r");
char buffer_line_template_file[100];
char buffer_line_data_file[100];
if (argc != 3)
{
perror("You didn't insert all the arguments!\n\n");
exit(EXIT_FAILURE);
}
if (template_file == NULL || data_file == NULL)
{
perror("Error while opening the file!\n\n");
exit(EXIT_FAILURE);
}
int counter = 0;
for (int i = 0; i < countlines(argv[1]); i++)
{
fgets(buffer_line_template_file, 100, template_file);
for (int j = 0; j < countlines(argv[2]); j++)
{
fgets(buffer_line_data_file, 100, data_file);
if (strcmp(buffer_line_template_file, buffer_line_data_file) != 0)
{
counter++;
printf("%d", counter);
}
}
}
printf("\n\n");
return 0;
}
Could someone please point me into the right direction ? For testing purposes I created a counter at the end which was a part of a small debug. There should be the print() function
As per #chux answer I got the following simplified code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *template_file = fopen(argv[1], "r");
FILE *data_file = fopen(argv[2], "r");
char buffer_line_template_file[100];
char buffer_line_data_file[100];
if (argc != 3)
{
perror("You didn't insert all the arguments!\n\n");
exit(EXIT_FAILURE);
}
if (template_file == NULL || data_file == NULL)
{
perror("Error while opening the file!\n\n");
exit(EXIT_FAILURE);
}
while(fgets(buffer_line_template_file, 100, template_file))
{
buffer_line_template_file[strcspn(buffer_line_template_file, "\n")] = '\0';
rewind(data_file);
while (fgets(buffer_line_data_file, 100, data_file))
{
buffer_line_data_file[strcspn(buffer_line_data_file, "\n")] = '\0';
if (strcmp(buffer_line_template_file, buffer_line_data_file) != 0)
{
printf("%s\n", buffer_line_template_file);
}
}
}
printf("\n\n");
return 0;
}
The above code is giving me the following output, which is not what is expected:
john
john
john
john
john
john
is
is
is
is
is
the new
the new
the new
the new
the new
the new
guy
guy
guy
guy
guy
guy
Problems with OP's code
Imprecise definition of line.
Excessive recalculation
Fuzzy determination of the number of lines in a file.
Unlike string, which has a precise definition in C, reading a line is not so well defined. The primary specificity issue: does a line contain the trailing '\n'. If the first answer is Yes, then does the last text in a file after a '\n' constitute a line? (Excessively long lines are another issue, but let us not deal with that today.)
Thus possibly some lines end with '\n' and others do not, fooling strcmp("dog", "dog\n").
The easiest solution is to read a line until either 1) a '\n' is encountered, 2) EOF occurs or 3) line buffer is full. Then after getting a line, lop off the potential trailing '\n'.
Now all lines code subsequently works with have no '\n'.
fgets(buffer_line_template_file, 100, template_file);
buffer_line_template_file[strcspn(buffer_line_template_file, "\n")] = '\0';
OP's loop is incredible wasteful. Consider a file with 1000 lines. Code will loop, calling 1000 times countlines() (each countlines() call reads 1000 lines) times when one countlines() call would suffice.
// for (int j = 0; j < countlines(argv[2]); j++)
int j_limit = countlines(argv[2]);
for (int j = 0; j < j_limit; j++)
There really is no need to count the line anyways, just continue until EOF (fgets() returns NULL). So no need to fix its fuzzy definition. (fuzzy-ness concerns same issues as #1)
int counter = 0;
for (fgets(buffer_line_template_file, 100, template_file)) {
buffer_line_template_file[strcspn(buffer_line_template_file, "\n")] = '\0';
rewind(data_file);
while ((fgets(buffer_line_data_file, 100, data_file)) {
buffer_line_data_file[strcspn(buffer_line_data_file, "\n")] = '\0';
if (strcmp(buffer_line_template_file, buffer_line_data_file) != 0) {
counter++;
printf("%d", counter);
}
}
}
Other simplifications possible - for another day.
FWIW, following counts lines of text allowing the last line in the file to optionally end with a '\n'.
unsigned long long FileLineCount(FILE *istream) {
unsigned long long LineCount = 0;
rewind(istream);
int previous = '\n';
int ch;
while ((ch = fgetc(inf)) != EOF) {
if (previous == '\n') LineCount++;
previous = ch;
}
return LineCount;
}
Note that this function may get a different result that fgets() calls. Consider a file of one line of 150 characters. fgets(..., 100,...) will report 2 lines. FileLineCount() reports 1.
[Edit] Updated code to conform to OP functionality.
int found = 0;
while (fgets(buffer_line_data_file, 100, data_file))
{
buffer_line_data_file[strcspn(buffer_line_data_file, "\n")] = '\0';
if (strcmp(buffer_line_template_file, buffer_line_data_file) == 0)
{
found = 1;
break;
}
}
if (!found) printf("%s\n", buffer_line_template_file);
This program prints the diff of two files file1.txt and file2.txt.
#include<stdio.h>
#include <stdlib.h>
#include <memory.h>
int main() {
FILE *fp1, *fp2;
int ch1, ch2;
char fname1[40], fname2[40];
char *line = NULL;
size_t len = 0;
ssize_t read;
char *line2 = NULL;
size_t len2 = 0;
ssize_t read2;
fp1 = fopen("file1.txt", "r");
fp2 = fopen("file2.txt", "r");
if (fp1 == NULL) {
printf("Cannot open %s for reading ", fname1);
exit(1);
} else if (fp2 == NULL) {
printf("Cannot open %s for reading ", fname2);
exit(1);
} else {
while ((read = getline(&line, &len, fp1)) != -1 && (read2 = getline(&line2, &len2, fp2)) != -1) {
if (!strcmp(line, line2)) {
printf("Retrieved diff on line %zu :\n", read);
printf("%s", line);
}
}
if (ch1 == ch2)
printf("Files are identical \n");
else if (ch1 != ch2)
printf("Files are Not identical \n");
fclose(fp1);
fclose(fp2);
}
return (0);
}
You already have a very good answer (and always will from chux), but here is a slightly different approach to the problem. It uses automatic storage to reading file2 into an array of strings and then compares each line in file1 against every line in file2 to determine whether it is unique. You can easily convert the code to dynamically allocate memory, but for sake of complexity that was omitted:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXC = 256, MAXL = 512 };
void file1infile2 (FILE *fp2, FILE *fp1, size_t *n2, size_t *n1);
int main (int argc, char **argv) {
FILE *fp1 = fopen (argc > 1 ? argv[1] : "file1.txt", "r");
FILE *fp2 = fopen (argc > 2 ? argv[2] : "file2.txt", "r");
size_t n1 = 0, n2 = 0;
if (!fp1 || !fp2) {
fprintf (stderr, "error: file open failed.\n");
return 1;
}
printf ("\nunique words in file1, not in file 2.\n\n");
file1infile2 (fp2, fp1, &n2, &n1);
printf ("\nanalyzed %zu lines in file1 against %zu lines in file2.\n\n",
n1, n2);
return 0;
}
void file1infile2 (FILE *fp2, FILE *fp1, size_t *n2, size_t *n1)
{
char buf[MAXC] = "";
char f2buf[MAXL][MAXC] = { "" };
size_t i;
*n1 = *n2 = 0;
while (*n2 < MAXL && fgets (buf, MAXC, fp2)) {
char *np = 0;
if (!(np = strchr (buf, '\n'))) {
fprintf (stderr, "error: line exceeds MAXC chars.\n");
exit (EXIT_FAILURE);
}
*np = 0;
strcpy (f2buf[(*n2)++], buf);
}
while (*n1 < MAXL && fgets (buf, MAXC, fp1)) {
char *np = 0;
if (!(np = strchr (buf, '\n'))) {
fprintf (stderr, "error: line exceeds MAXC chars.\n");
exit (EXIT_FAILURE);
}
*np = 0, (*n1)++;
for (i = 0; i < *n2; i++)
if (!(strcmp (f2buf[i], buf)))
goto matched;
printf (" %s\n", buf);
matched:;
}
}
Look over the code and let me know if you have any questions.
Example Use/Output
$ ./bin/f1inf2 dat/f1 dat/f2
unique words in file1, not in file 2.
john
the new
guy
analyzed 4 lines in file1 against 6 lines in file2.
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';
}