Replace "a", "an", "the" with blank space in a text file - c

A friend of mine gave me a task to write a program to
replace "a", "an", "the" with blank space in a text file in C.
I wrote that program, but that went too lengthy as I checked "a", "an", "the" individually.
For example, I replaced "a" by
NOTE: fs is pointer to the source file and ft is pointer to the target file.
while(fgets(str, 100, fs) != NULL)
{
for(i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ' ||
str[i] == '.' ||
str[i] == ',' ||
str[i] == '\n' ||
str[i] == '\t')
{
if (str[i+1] == 'a' || str[i+1] == 'A')
{
if (str[i+2] == ' ' ||
str[i+2] == '.' ||
str[i+2] == ',' ||
str[i+2] == EOF ||
str[i+2] == '\0' ||
str[i+2]== '\n' ||
str[i+2]== '\t')
{
str[i+1]=' ';
}
}
}
}
fputs(str,ft);
}
Is there a shorter way to do the same?
Take care of the fact that "a", "an", "the" can be the first words in the source file.

Use the fscanf and fprintf functions so that scanning the file would be easy for you and you can easily check for 'a, an, the':
char s[50];
while(fscanf(fp, "%s", s) != EOF)
{
if(strcmp(s, "a") == 0 || strcmp(s, "an") == 0 || strcmp(s, "the") == 0)
{
char c = ' ';
fprintf(ft, "%s", c);
}
else
{
fprintf(ft, "%s", s);
}
}

You can read the input char-by-char, using for example getchar, or always remember the last few chars, even if they were in the previous buffer. This way you need to remember the previous two chars, and the current char in a little "rolling-array", that you would reset at each word boundary.
Using a fixed sized buffer with fgets, or fscanf, you need a lot of codeing to handle special cases. There are a few, for example the lines don't start with space or tab, but a line parhaps starts with "the". In that case, there will be no such character before the word. The same thing is true about whitespace following a word. You can get around these things by allocating a bit more space for the buffer, fill the first char with ' ' , and call fgets this way:
fgets(str + 1, 99, fs)
But you still have the problem of words at boundaries, where your buffer ends with "... t" and the next fgets gives you "he ..." .
Just keep an array of 3 chars, and the current length of the array, resetting the length to zero at each word boundary.

I think this code works for a reasonably plausible definition of the problem:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static char const *words[] = { "a", "the", "an" };
enum { NUM_WORDS = sizeof(words) / sizeof(words[0]) };
static void mapword(char *word, int len)
{
char lower[256];
word[len] = '\0';
for (int i = 0; i <= len; i++)
lower[i] = tolower(word[i]);
for (int i = 0; i < NUM_WORDS; i++)
{
if (strcmp(words[i], lower) == 0)
{
putchar(' ');
return;
}
}
fputs(word, stdout);
}
int main(void)
{
char word[256];
int c;
size_t nletters = 0;
while ((c = getchar()) != EOF)
{
/*
** This would break if you enter a word with 256 characters
** ending in 'a' because the word would be split after 255
** characters and the trailing 'a' would then match the
** next buffer full, which is an awfully improbable event.
*/
if (!isalpha(c) || nletters >= sizeof(word)-1)
{
if (nletters > 0)
{
mapword(word, nletters);
nletters = 0;
}
putchar(c);
}
else
word[nletters++] = c;
}
if (nletters > 0)
{
/*
** Since a text file should end with a newline, the program
** should not get here!
*/
mapword(word, nletters);
}
return 0;
}
For example, given the first three lines of the question as input:
A friend of mine gave me a task to write a program to
replace "a", "an", "the" with blank space in a text file in c.
I wrote that program but that went too lengthy as I checked "a", "an", "the" individually.
the output from the program is:
friend of mine gave me task to write program to
replace " ", " ", " " with blank space in text file in c.
I wrote that program but that went too lengthy as I checked " ", " ", " " individually.

If you want to use some system command then your life is easy. sed is linux command to serve your requirement.
You can do as follows
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
system("sed 's/an//g;s/a//g;s/the//g' file");
}
If file contain
replace “a”, “an”, “the” with blank space in a text file
Output is
replce “”, “”, “” with blk spce in text file
Caution : This code replace space every where when it found matching pattern.So it not check for matching whole word.

Related

C looping using EOF, how to read next line?

I'm facing an issue while trying to resolve a particular problem in C. User input must be read in encrypted form and the output must be the decrypted message, that is, it is a replacement cipher.The problem is that when I read the first input, the program loops printing the decrypted message, it doesn't ask to read other inputs. I'm really confused about this as I was told that I should use EOF, something I'm not very knowledgeable about. I could even solve it another way, but I need to implement the EOF, and because I don't know that, I'm having difficulty solving the exercise.
I am aware that the code I created is not the best for the resolution, however, it might work if someone helps me with this loop issue.
Source Code
#include <stdio.h>
#include <string.h>
void alterChar(int i, char phrase[])
{
for (i = 0; phrase[i] != '\0'; i++)
{
if (phrase[i] == '#')
{
phrase[i] = 'a';
}
if (phrase[i] == '&')
{
phrase[i] = 'e';
}
if (phrase[i] == '!')
{
phrase[i] = 'i';
}
if (phrase[i] == '*')
{
phrase[i] = 'o';
}
if (phrase[i] == '#')
{
phrase[i] = 'u';
}
printf("%s\n", phrase);
}
}
int main()
{
int i;
char phrase[256];
while (scanf("%[^\n]s", phrase) != EOF)
{
///scanf(" %[^\n]s", phrase);
alterChar(i, phrase);
}
return 0;
}
The line
while (scanf("%[^\n]s", phrase) != EOF)
is wrong, for several reasons:
You seem to be undecided on whether to use the %s or the %[] conversion format specifier. The character s is not part of the %[] format specifier. Therefore, when using your format string, scanf will attempt to match a literal s. This is probably not what you want, so it should be removed from the format string.
If scanf is unable to match any characters because the line is empty, it will return 0 and will not touch the contents of phrase. However, you are incorrectly treating the return value of 0 as success.
If the user enters more than 255 characters, then you will be writing to the array phrase out of bounds, causing undefined behavior (i.e your program may crash). Therefore, you should limit the number of matched characters to 255 characters, so that the function won't write more than 256 characters (including the terminating null character of the string).
For the reasons stated above, you should change the line to the following:
while ( scanf( "%255[^\n]", phrase ) != 1 )
Also, this scanf statement will not consume the newline character from the input stream, so the next function call to scanf will fail. Therefore, you must call a function to consume the newline character from the input stream, for example by calling getchar, or by telling scanf to consume all whitespace input beforehand, like this:
while ( scanf( " %255[^\n]", phrase ) != 1 )
Alternatively, you could use the function fgets instead (which I recommend), as that function will also consume the newline character and write it to the string.
while ( fgets( phrase, sizeof phrase, stdin ) != NULL )
When using the function fgets, you should also verify that an entire line was read in, for example by writing the following code afterwards:
//verify that entire line was read in
if ( strchr( phrase, '\n' ) == NULL )
{
printf( "line to long for input buffer!\n" );
exit( EXIT_FAILURE );
}
Note that if you decide to use the function fgets, you will have an additional newline character at the end of the line, instead of only a '\0', so in the function alterChar, you will have to change the line
for (i = 0; phrase[i] != '\0'; i++)
to
for (i = 0; phrase[i] != '\n'; i++)
Another problem in your code is that the line
alterChar(i, phrase);
does not make sense. You are passing the value of an uninitialized variable to the function.
You should probably change the function prototype from
void alterChar(int i, char phrase[])
to
void alterChar( char phrase[] )
and maybe also give the function a better name, as it does not deal with single characters, but whole strings, and also prints it:
void alterAndPrintPhrase( char phrase[] )
Also, in that function, you should move the line
printf("%s\n", phrase);
outside the loop.
After applying all the fixes mentioned above, your code should look like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void alterAndPrintPhrase( char phrase[] )
{
for ( int i = 0; phrase[i] != '\n'; i++ )
{
if (phrase[i] == '#')
{
phrase[i] = 'a';
}
if (phrase[i] == '&')
{
phrase[i] = 'e';
}
if (phrase[i] == '!')
{
phrase[i] = 'i';
}
if (phrase[i] == '*')
{
phrase[i] = 'o';
}
if (phrase[i] == '#')
{
phrase[i] = 'u';
}
}
printf( "%s\n", phrase );
}
int main()
{
char phrase[256];
while ( fgets( phrase, sizeof phrase, stdin ) != NULL )
{
//verify that entire line was read in
if ( strchr( phrase, '\n' ) == NULL )
{
printf( "line to long for input buffer!\n" );
exit( EXIT_FAILURE );
}
alterAndPrintPhrase( phrase );
}
return 0;
}
This program has the following behavior:
Input:
Th!s !s # t&st.
Output:
This is a test.
i think just putting the printf outside of the loop help and use feof (fetch en of file) to know where you are.
#include <stdio.h>
#include <string.h>
void alterChar(char phrase[]) {
for (int i = 0; phrase[i] != '\0'; i++) {
if (phrase[i] == '#') {
phrase[i] = 'a';
}
if (phrase[i] == '&') {
phrase[i] = 'e';
}
if (phrase[i] == '!') {
phrase[i] = 'i';
}
if (phrase[i] == '*') {
phrase[i] = 'o';
}
if (phrase[i] == '#') {
phrase[i] = 'u';
}
}
printf("%s\n", phrase);
}
int main() {
char phrase[256];
while (!feof(stdin)) {
scanf(" %[^\n]s", phrase);
alterChar(phrase);
}
return 0;
}

delete trailing char in line without using string library C

started C this semester and struggling to convert knowledge of java into C. The code compiles and runs but not as I want it. The task is to write a code that read a text file line by line (I have a get line function) and outputs new text file keeping line formatting the same (meaning that if original file has 4 line output file has to have 4 line) but deleting trailing characters (space and \t). I've spend enormous amount of time pocking at this thing without success. Any help is appreciated.
hw2_execcise_1. program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.
Pseudo::: while (there are lines to read)
find end of line1 (\n)
save length
going from the end of the line towards the beginning
find char that is not either space or tab
and insert \n following found char.
#include <stdio.h>
#define LINELIM 1000
int getLine(char s[], int lim);
int main (void){
int len, i;
char line1[100];
while ((len = getLine(line1, LINELIM)) >0){
for (i=len; i>=0; i--){
if ((line1[i] == ' ') || (line1[i] == '\t')){
line1[i] = '\n';
}
else break;
}
printf(" %s\n", line1);
}
return 0;
}
/*getline: read a line into s, return length*/
int getLine(char s[], int lim){
int c,i;
for (i=0; i<lim-1 && (c=getchar())!= EOF && c!='\n'; ++i)
s[i]=c;
if (c == '\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
while ((len = getLine(line1, LINELIM)) >0){
for (i=len-1; i>=0; i--){//-1 for 0 origin
if(line1[i] == ' ' || line1[i] == '\t' || line1[i] == '\n'){//add case of '\n'
line1[i] = '\0';//newline add print part
}
else break;
}
if(line1[0])//not blank line
printf("%s\n", line1);
}
the main logic problem with the code is
1) the getline function is terminating each input line with (either) '\n''\0' or with '\0'
2) the main function is not checking for the newline when it checks for space or tab. I.E. it needs to also check for newline --or-- getline() should not ever include the newline

printing a word per line

I need to write a program that prints its input one word per line. Here's what I got so far:
#include <stdio.h>
main(){
int c;
while ((c = getchar()) != EOF){
if (c != ' ' || c!='\n' || c!='\t')
printf("%c", c);
else
printf("\n");
}
}
The logic is pretty simple. I check to see if the input is not a newline, tab or space, and in that case it prints it, otherwise prints a newline.
When I run it, I get results like this:
input--> This is
output--> This is
It prints the whole thing. What goes wrong here?
if (c != ' ' || c!='\n' || c!='\t')
This will never be false.
Perhaps you meant:
if (c != ' ' && c!='\n' && c!='\t')
instead of using printf try putchar, also as per above comments, you should use && instead of ||.
here is my code-
#include<stdio.h>
main()
{
int c, nw; /* nw for word & c for character*/
while ( ( c = getchar() ) != EOF ){
if ( c != ' ' && c != '\n' && c != '\t')
nw = c;
else {
nw = '\n';
}
putchar (nw);
}
}
this code will give you the desired output
you can use if you want the strtok function in string.h library which can cut the input into many words by providing a delimiter.
Here is a perfect code commented which can fit to your needs
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char line[1000]=""; // the line that you will enter in the input
printf("Input the line:\n>>");
scanf("%[^\n]",line); // read the line till the you hit enter button
char *p=strtok(line," !#$%&'()*+,-./'"); // cut the line into words
// delimiter here are punctuation characters (blank)!#$%&'()*+,-./'
printf("\nThese are the words written in the line :\n");
printf("----------------------------------------\n");
while (p!=NULL) // a loop to extract the words one by one
{
printf("%s\n",p); // print each word
p=strtok(NULL," !#$%&'()*+,-./'"); // repeat till p is null
}
return 0;
}
If we execute the code above we will get
Input the line:
>>hello every body how are you !
These are the words written in the line :
----------------------------------------
hello
every
body
how
are
you
suggest the code implement a state machine,
where there are two states, in-a-word and not-in-a-word.
Also, there are numerous other characters that could be read
(I.E. ',' '.' '?' etc) that need to be check for.
the general logic:
state = not-in-a-word
output '\n'
get first char
loop until eof
if char is in range a...z or in range A...Z
then
output char
state = in-a-word
else if state == in-a-word
then
output '\n'
state = not-in-a-word
else
do nothing
end if
get next char
end loop
output '\n'
I think the simple solution would be like
#include <stdio.h>
int main(void) {
// your code goes here
int c;
while((c=getchar())!=EOF)
{
if(c==' ' || c=='\t' || c=='\b')
{
printf("\n");
while(c==' ' || c=='\t' || c=='\b')
c=getchar();
}
if(c!=EOF)
putchar(c);
}
return 0;
}

char pointer allocates random characters

I am writing a small C code for class that plays Hangman with an already input name. One section requires I allow the output of the input phrase with * in the place of all letters, but not punctuation. Similarly, at the end of the phrase, the name of the user is put in parentheses and is meant to be printed as is. The first section of the code works fine, the first while loop which places the asterisks, but the second while loop seems to fail every time and seems to store nonsense and random characters everytime the program is run. Here is the program I have so far.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int guesses = 3;
int limit = 41;
char quote[42] = "I just wrote this game in C! (Josh Masher)";
char strArr[42];
char *quoP;
quoP = &quote[0];
char *strP;
strP = &strArr[0];
while (*quoP != '.' && *quoP != '!' && *quoP != '?') {
if (isalpha(*quoP)) {
*strP = '*';
} else if (*quoP == ' ' || *quoP == ',') {
*strP = *quoP;
}
strP++;
quoP++;
}
while (*quoP != NULL) {
*strP = *quoP;
strP++;
quoP++;
}
}
any ideas?
EDIT
I rewrote the code slightly, and erased the random character problem, but it is more complicated now.
int main()
{
int guesses = 3;
int limit = 41;
char quote[42] = "I just wrote this game in C! (Alex Butler)\0";
char strArr[42];
char *quoP;
quoP = &quote[0];
char *strP;
strP = &strArr[0];
int counter = 0;
while (*quoP != '\0') {
if (*quoP == '.' || *quoP == '!' || *quoP == '?' || counter == 1) {
counter = 1;
}
if (isalpha(*quoP)) {
if (counter == 0) {
*strP = '*';
} else if (counter == 1) {
*strP = *quoP;
}
} else {
*strP = *quoP;
}
printf("%c", *strP);
strP++;
quoP++;
}
}
Add *strP = '\0' after the last while loop to terminate the string.
Also, (*quoP != NULL) should be (*quoP != '\0') . The type of NULL is pointer, the type of *quoP is character. Your program will still work, but it's misleading.
Also might want to include ctype.h
Good luck with the rest of your project.
The first loop doesn't work fine. If it encounters unhandled punctuation (such as &), it will skip right over and leave junk there.
You do not null-terminate the string either, as others have pointed out in the comments. You would do better to copy the string first (with strncpy) and then stamp characters with * as you deem appropriate. That means you only have one loop, and it'll be a lot simpler:
strncpy( strArr, quote, sizeof(strArr) );
for( char *s = strArr; !strchr(".!?", *s); s++ )
{
if( isalpha(*s) ) *s = '*';
}
Also, NULL is a pointer. Null-termination is an unfortunate name for this. You can write the value 0 or '\0', but not NULL.

C Program that counts Words and Lines in Standard input

I am new to C programming and I am currently trying to teach myself how to create a C program that can count words and lines in the input stream and print the two totals to the standard output.
What I am actually trying to do is to have the program count the number of lines and count the number of words depending on the definition of a word in which I feel that I am off.
I want the words to exclude blanks, tabs, newlines, hyphens, or colons. While having the program output the results (words and lines) as decimals.
#include<stdio.h>
int main()
{
int iochar;
int words;
int lines;
printf("Enter something here:\n\n");
while ((iochar = getchar ()) !=EOF)
{
if((iochar == ' ') || (iochar == '\t') || (iochar == '\n'))
putchar(iochar);
}
return 0;
}
Am I totally off on this program?
If your question is how to fix the compile error, that's simple. Add one more closing brace at the end.
But your program will still do only one pass through the loop and will print only one character if and only if the user types a space, tab or newline. No matter what the user types, the program will then terminate. I doubt that's what you wanted.
I suspect this is what you intended:
while ((iochar = getchar ()) !=EOF)
{
if((iochar == ' ') || (iochar == '\t') || (iochar == '\n'))
{
putchar(iochar);
}
}
return 0;
After your "I am trying to have thee numbers be right justified in an 8-column field ..." I cannot understand what you are trying to say :(
int words = 0;
int lines = 0;
char buffer[1024];
while(fgets(buffer, sizeof buffer, stdin))
{
lines++;
if(buffer[0] == '\n')
continue;
char *tmp = buffer-1;
while(tmp = strchr(tmp+1, ' '))
words++;
words++; /* count last word before \0*/
}
printf("lines: %d, words: %d\n", lines, words);
is that what you need/want?
The error message is:
Test.c:20:1: error: expected declaration or statement at end of input
It does not compile because you are missing a }.
Had you properly indented your code, like so, you would have found your mistake:
#include<stdio.h>
int main() {
int iochar;
int words;
int lines;
printf("Enter something here:\n\n");
while ((iochar = getchar ()) !=EOF)
{
if((iochar==' ')||(iochar=='\t')||(iochar=='\n'))
{
putchar(iochar);
iochar = getchar();
}
return 0;
}
Yet another example of the importance of readability :)

Resources