Convert and count upper case and lowercase characters - c

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.

Related

Copy words with given letter from file to new file

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;
}

trying to store a text file into an array

i am trying to read from a text file and store it into an array character by character, ive tested it out by trying to print or check the ii count but it doesn't seem to be storing, any help would be muchly appreciated
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
char ch = '\0';
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
free(file);
return file;
}
I have commented out the line containing the code to free the character array before returning, which was basically making the pointer invalid. I have also changed the type of the variable "ch" to int as fgetc() returns integer.
#include <stdio.h>
#include <stdlib.h>
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
int ch; //changed to int from char.
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
// printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
//free(file); //commented this line out
return file;
}
int main()
{
char *filename = "sample.txt";
char *file_arr = readFile(filename);
printf("%s \n",file_arr);
return 0;
}

C program to print line number in which given string exists in a text file

I have written a C program that opens a text file and compares the given string with the string present in the file. I'm trying to print the line number in which the same string occurs, but I am unable to get the proper output: output does not print the correct line number.
I would appreciate any help anyone can offer, Thank you!
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
int num = 0, line_number = 1;
char string[50];
char student[100] = { 0 }, chr;
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 \n");
scanf("%s", student);
while (fscanf(in_file, "%s", string) == 1) {
if (chr == '\n') {
if (strstr(string, student) == 0) {
break;
} else
line_number += 1;
}
}
printf("line number is: %d\n", line_number);
fclose(in_file);
}
return 0;
}
You cannot read lines with while (fscanf(in_file, "%s", string), the newlines will be consumed by fscanf() preventing you from counting them.
Here is an alternative using fgets():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char string[200];
char student[100];
int num = 0, line_number = 1;
FILE *in_file = fopen("student.txt", "r");
if (in_file == NULL) {
printf("Error file missing\n");
exit(1);
}
printf("please enter a word \n");
if (scanf("%s", student) != 1) {
printf("No input\n");
exit(1);
}
while (fgets(string, sizeof string, in_file)) {
if (strstr(string, student)) {
printf("line number is: %d\n", line_number);
}
if (strchr(string, '\n')) {
line_number += 1;
}
fclose(in_file);
}
return 0;
}

How do I count the number of characters in a file?

I have copied the contents of a file to another file and I am trying to get the line, word, and character count. The code I have right now displays the number of lines and words in the file content. Now I need to display the character count but I am unsure of how to do that. I am guessing a for loop? But I am not sure.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_WORD_LEN 100
#define MAX_LINE_LEN 1000
#define ipsumFile "Lorem ipsum.txt"
#define ipsumCopy "Lorem ipsum_COPY.txt"
int wordCount(FILE *fp);
int charCount(FILE *fp);
int sendContentTo(FILE *fp, FILE *out);
int getWordAt(FILE *fp, int pos, char *word);
int appendToFile(char *fileName, char *newText);
int main(void)
{
FILE *fp, *fp2; //"file pointer"
int ch; //place to store each character as read
//open Lorem ipsum.txt for read
if ((fp = fopen(ipsumFile, "r")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumFile);
exit(EXIT_FAILURE);
}
//open Lorem ipsumCopy for writing
if ((fp2 = fopen(ipsumCopy, "w+")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumCopy);
exit(EXIT_FAILURE);
}
//print out and count all words in Lorem ipsum.txt
int numOfWords = wordCount(fp);
//print out and count all lines in Lorem ipsum.txt
int numOfLines = sendContentTo(fp, stdout);
//copy the content of Lorem ipsum.txt into a new file (ipsumCopy)
numOfLines = sendContentTo(fp, fp2);
fclose(ipsumFile);
fclose(ipsumCopy);
// close Lorem ipsum.txt
if (fclose(fp) != 0)
fprintf(stderr, "Error closing file\n");
if (fclose(fp2) != 0)
fprintf(stderr, "Error closing copy\n");
return 0;
}
int sendContentTo(FILE *in, FILE *out)
{
fprintf(stdout, "Performing file copy...\n\n");
//start at the beginning of the file
rewind(in);
// array to hold one line of text up to 1000 characters
char line[MAX_LINE_LEN];
int lineCount = 0;
// read one line at a time from our input file
while (fgets(line, MAX_LINE_LEN, in) != NULL)
{
//send line we just read to output.
fprintf(out, "%s", line);
//count the lines
lineCount++;
}
fprintf(stdout, "\nFinished line count.\n");
fprintf(stdout, "Count is: %d.\n\n", lineCount);
// Return how many text lines
// we've processed from input file.
return lineCount;
}
// Read content from file one character at a time.
// Returns number of total characters read from the file.
int charCount(FILE *fp)
{
fprintf(stdout, "Performing char count...\n\n");
rewind(fp);
int charCount = 0;
char ch;
//print out each character, and return the
// number of characters in the file.
fprintf(stdout, "\nFinished character count. \n");
fprintf(stdout, "Count is: %d. \n\n", charCount);
return charCount;
}
// Read content from file one word at a time.
// Returns number of total words read from the file.
int wordCount(FILE *fp)
{
fprintf(stdout, "Performing word count...\n\n");
rewind(fp);
char word[MAX_WORD_LEN];
int wordCount = 0;
while (fscanf(fp, "%s", word) == 1)
{
// Send entire word string
// we just read to console
puts(word);
//count the word
wordCount++;
}
fprintf(stdout, "\nFinished word count.\n");
fprintf(stdout, "Count is: %d.\n\n", wordCount);
return wordCount;
}
You don't need to write different function for counting the number of lines, words, and characters in a file. You can do it in a single parsing of file character by character and while parsing, in order to copy the content of file to another file, you can write the characters to another file. You can do:
#include <stdio.h>
#include <stdlib.h>
int count_and_copy(const char * ipsumFile, const char * ipsumCopy)
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0, c;
FILE *fp, *fp2;
if ((fp = fopen(ipsumFile, "r")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumFile);
exit(EXIT_FAILURE);
}
if ((fp2 = fopen(ipsumCopy, "w+")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumCopy);
exit(EXIT_FAILURE);
}
while((c = fgetc(fp)) != EOF)
{
fputc(c, fp2); // write character c to the copy file
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
fclose (fp2);
printf ("Number of lines : %u\n", lCount);
printf ("Number of words : %u\n", wCount);
printf ("Number of characters : %u\n", cCount);
return 0;
}
int main()
{
/* Assuming, you want to count number of lines, words
* and characters of file1 and copy the contents of file1
* to file2.
*/
count_and_copy("file1", "file2");
return 0;
}
I suppose that the following approach will work:
void *cw(const char *fname)
{
FILE *f = fopen(fname, "r");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", fname, strerror(errno));
exit(EXIT_FAILURE);
}
int bc = 0; /* bytes counter */
int wc = 0 ; /* words counter */
int nlc = 0; /* new lines counter */
const int in_word_state = 0;
const int out_word_state = 1;
int state = out_word_state;
int c = 0;
for (;;) {
c = fgetc(f);
if (ferror(f) != 0) {
perror("fgetc");
goto error;
}
if (feof(f))
break;
if (c == '\n')
nlc++;
if (c == ' ' || c == '\t' || c == '\n')
state = out_word_state;
if (state == out_word_state) {
state = in_word_state;
wc++;
}
bc++;
}
if (fclose(f) == EOF) {
perror("fclose");
goto error;
}
printf("w: %d, c: %d, l:%d\n", wc, bc, nlc);
error:
if (f != NULL) {
if (fclose(f) == EOF) {
perror("fclose");
}
}
exit(EXIT_FAILURE);
}

Reading a file word by word with no ending chars

I have this small program in C that reads through a file a compares word by word,
how can I assure that words like "this," won't be read as a word? I would like it to read as "this"
int main(int argc, char *argv[]) {
if(argc != 3)
{
printf("Usage: ./sw <word> <filename> \n");
exit(1);
}
char* word = argv[1];
const char* filename = argv[2];
FILE* file = fopen(filename, "r");
if(file == NULL)
{
printf("Could not open file\n");
exit(1);
}
//Assuming one word can not have more than 250 chars
char w[250], check_eof;
do
{
check_eof = fscanf(file, "%s", w);
if(strcmp(word, w) == 0)
{
printf("W : %s \n", w);
}
} while(check_eof != EOF);
fclose(file);
return 0;
}
You can check if a char belongs to a word like this
int c = fgetc(file);
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
// c belongs to a word
word[n++] = c;
} else {
// end of word
if (strncmp(word, w, n) == 0) {
// word and w match!
}
}
If you #include <ctype.h>, then you can call isalpha(c) instead to test it.
In the code below, I use isalpha() and I copy the result string in a new buffer named res. However, this procedure can be done in-place, but I'll leave now for the sake of simplicity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h> // for isalpha()
int main(int argc, char *argv[]) {
char* word = "this";
const char* filename = "test.txt";
FILE* file = fopen(filename, "r");
if(file == NULL)
{
printf("Could not open file\n");
exit(1);
}
//Assuming one word can not have more than 250 chars
// ATTENTION, it is 249 chars, do NOT forget of the null terminator
char w[250], res[250];
int check_eof; // should be of type int, for EOF checking
do
{
check_eof = fscanf(file, "%s", w);
// what if 'word' appears as the last word
// in the file? You should check for eof
// right after fscanf()
if(check_eof == EOF)
break;
int i = 0, j = 0;
while (w[i]) // parse what we read
{
if (isalpha(w[i]))
res[j++] = w[i]; // keep only the alphabetic chars
i++;
}
res[j] = '\0'; // it should be a null terminated string
if(strcmp(word, res) == 0) // compare to 'res' now
{
printf("W : %s \n", res);
}
} while(1); // the terminating step is inside the body now
fclose(file);
return 0;
}

Resources