C Program to Append Letter(s) to End of File - c

Open an existing text file and append new letter
to this file as long as user wants to add new
letter to the file.
Use while loop
Use fopen (“filename”, “a”);
I have no idea where to start on this. I understand how to append a single letter, word or phrase to a file, but I have no idea to do the other operation on top of that. Any help is much appreciated.
OK, so I wanted to work on writing the while loop part separately and just have it print the output to see if I was on the right track...
Here is what I have so far..
What I still need help with is how to end the while loop (by using a specific character)
How to integrate this into the file format and get it to print the characters onto the file.
#include <stdio.h>
int main()
{
int true;
char mychar;
char NUL;
NUL =000;
while(true)
{
printf("\nEnter a letter to append to file A.txt: ");
scanf(" %c", &mychar);
if(mychar == (char)000)
break;
}
return 0;
}

Use a while loop to achieve this :
#include <stdio.h>
int main(void)
{
char c;
FILE *file;
file = fopen("file.txt","a");
//you can use EOF instead if '\n'
while( (c = getc(stdin)) != '\n' )
{
putc(c,file);
}
fclose(file);
return 0;
}

Related

What is wrong with my for loop and my strcmp?

Right now, the purpose of the code is to take a user input and compare it to a text file (all in code blocks or C programming). The text file reads as:
Leia 12345
Darth 23456
R2D2 34567
Solo 45678
Jabba 56789
Yoda 67890
The code was able to combine the two strings together, but it wont recognize a correct answer nor will the for loop end after 3 tries like it's supposed to. I believe there is something wrong with my for loop, the reading of the text file, and the string comparison. And I have no idea how to fix it.
#include <stdio.h> /* for printf(), scanf() */
#include <stdlib.h> /* for system() */
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <math.h>
int main()
{
char name[5];
char pin[6];
FILE *file;
file = fopen("ident.txt", "r"); /*How to open, read, and print a text file */
char name2[11];
int i;
int c;
c = getc(file);
fgets(name2, sizeof(name2), file);
if (file == NULL)
{
printf("Error: could not open file %s", file);
return 1;
}
while (c != EOF)
{
printf("\n\tEnter your name: ");
scanf("%s", name); /*How to convert a user input into strings*/
printf("\n\tEnter your pin number: ");
scanf("%s", pin); /*How to convert a user input into strings*/
strcat(strcat(name, " "), pin); /*How to combine two user input string into one*/
printf("\n\n Entry: %s \n\n", name);
for (i = 0; i = 3; i++)
{
if (strcmp(name2, name) == 0)
{
printf("It's a Match");
}
else
{
printf("Invalid Entry. Try Again. \n");
break;
}
}
fclose(file);
}
return 0;
}
A couple of point that may help you:
It is not completely clear from your questrion what the goal of the program is - but if you're struggling it may be a good idea to try and solve a smaller version of the problem. Try making a smaller file with just one word of text, then prompt the user for input that will be compared against that single word.
You call getc(file) and fgets(name2, sizeof(name2), file) to read from the file before you check whether it has been oppen successfully - this should happen afterwards.
You generally don't check the string bouds when writing to them (and they are very small). If a user inputs a string that is longer than what the array fits, an overflow could happend and lead to unpredictable bugs. Try replacing scanf() with fgets() or a different function that lets you determine how many characters you will read.
Your for loop looks like this: (i = 0; i = 3; i++). Here's what it does:
Once, when entering the loop, set the variable i to 0.
Every time the code inside the loop is executed increase i by one.
Before re-entering the loop, set i to 3. If i is 0, exit the loop.
What you probably want is (i = 0; i < 3; i++)
Every run of the loop will do the same thing - comparing name2 to name. If you want to do something else, you should probably keep reading from the file and prompting the user for input inside the loop.
The while (c != EOF) loop will never end once entered, if you do not modify the content of c inside the loop.
From my comments:
In for (i = 0; i = 3; i++), the conditional expression is i = 3; which is actually an assignment operator and not a comparison operator. This will loop infinitely. Did you mean (e.g.) for (i = 0; i < 3; i++)? But, why have the for loop at all?
You only read one line from the text file and then loop on the user prompt/input. I think you want to restructure so that after prompting the user for and getting the name and pin, it is then that you want to loop through all lines of the file to look for a match. But, you'd have to reread the file on each failed user attempt [or store the data in a dynamically allocated array]
When you read a line from the file, you use fgets and get the whole line, including the trailing newline character [which you should strip (e.g.) name2[strcspn(name2,"\n")] = 0. When you prompt the user you're using scanf to get the name and pin separately. Combining with strcat to get a whole line isn't the best way. You could take file input the same way as you do user input and do two strcmp, one for name and the other for pin
You are doing break on your else but you probably want it on your if (i.e. you want to stop when there is a match and not a mismatch).
The easiest way to fix this is to put the file read and comparison into a function. Then, main can loop on the user prompt/input and call the function to do the matching.
Additionally, if the input file can not be opened, the program is printing an error message but trying to print file (a FILE *) with "%s" instead of the file's name (e.g. ident.txt)
Unfortunately, I had to do a lot of restructuring to get the code to work. There were just so many issues that it's difficult to list them all.
But, here is the refactored and working code:
#include <stdio.h> /* for printf(), scanf() */
#include <stdlib.h> /* for system() */
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include <math.h>
// findmatch -- find match for user name/id in file
int
findmatch(const char *name)
{
FILE *xfin;
const char *filename = "ident.txt";
char buf[100];
int match = 0;
xfin = fopen(filename, "r");
if (xfin == NULL) {
printf("Error: could not open file %s -- %s\n",
filename,strerror(errno));
exit(1);
}
while (fgets(buf,sizeof(buf),xfin) != NULL) {
// strip newline
buf[strcspn(buf,"\n")] = 0;
// match "name pid"
if (strcmp(buf,name) == 0) {
match = 1;
break;
}
}
fclose(xfin);
return match;
}
int
main(void)
{
int i;
int match;
char name[100];
char pin[100];
// do only so many tries before kicking out user
for (i = 0; i < 3; i++) {
printf("\n\tEnter your name: ");
scanf("%s", name);
printf("\n\tEnter your pin number: ");
scanf("%s", pin);
/* How to combine two user input string into one */
// NOTE: there may be a cleaner way to do this, but the code will work
strcat(strcat(name, " "), pin);
printf("\n\n Entry: %s \n\n", name);
match = findmatch(name);
if (match) {
printf("It's a Match\n");
break;
}
printf("Invalid Entry. Try Again. \n");
}
if (! match) {
printf("Too many retries\n");
exit(1);
}
printf("Doing stuff ...\n");
return 0;
}

How to copy every n-th characters from one char array to another?

I have a program that reads file A and then copies the contents to file B.
I would like to write to file B every third character. I created a loop that rewrites every third item to a new char array. In file B I get strange characters. What am I doing wrong?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
int i;
char full_string[100];
char reduce_string[100];
char file_name_for_read[128];
char file_name_for_save[128];
printf("Enter file name for read...\n");
scanf ("%s", file_name_for_read);
strcat(file_name_for_read,".txt");
FILE *fileA;
fileA=fopen(file_name_for_read,"r");
printf("Enter file name for save...\n");
scanf ("%s", file_name_for_save);
strcat(file_name_for_save,".txt");
FILE *fileB;
fileB=fopen(file_name_for_save,"w");
while(fgets(full_string, sizeof(full_string), fileA) !=NULL)
{
for(i = 2; i < 100; i+=3)
{
reduce_string[i-=2] = full_string[i+=1];
}
fprintf(fileB, "%s", reduce_string);
}
fclose(fileA);
fclose(fileB);
}
What am I doing wrong?
Several things. At minimum,
In your inner loop, you iterate over the full length of full_string, regardless of how many of those bytes were actually read from the file by the most recent fgets().
In your inner loop, you invoke undefined behavior because the expression reduce_string[i-=2] = full_string[i+=1] has two side effects on the value of i that are unsequenced relative to each other.
In that expression, i - 2 is anyway not the index you want except when i is 2, because you increment i by 3 at each iteration. You'll end up filling some positions and skipping others.
You do not add a null terminator at the end of the data copied into reduce_string.
Your strategy does not anyway result in copying every third character of the file; rather, it copies every third character of each line. These differ unless all the line lengths of the input files are multiples of 3.
reads file A and then copies the contents to file B. I would like to write to file B every third character.
If lines are not important,
seems simple to read 3 characters and write the 3rd one.
for(;;) {
fgetc(fileA);
fgetc(fileA);
int ch = fgetc(fileA);
if (ch == EOF) break;
fputc(ch, fileB);
}
or
int ch;
do {
fgetc(fileA);
fgetc(fileA);
ch = fgetc(fileA);
} while (ch != EOF && fputc(ch, fileB) != EOF);
The easiest way is to use a different index for each array, that way each can go at their own speed.
int i,x;
for(i = 0, x=0; i < 1000; i+=3, x++)
{
reduce_string[x] = full_string[i];
}
fprintf(fileB, "%s", reduce_string);
Check this code out. In your code, you have reduce_string[i-=2] = full_string[i+=1]; — I don't know where you come up with it, but this was not working.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
int i;
char full_string[100];
char reduce_string[100];
char file_name_for_read[128];
char file_name_for_save[128];
printf("Enter file name for read...\n");
scanf ("%s", file_name_for_read);
strcat(file_name_for_read,".txt");
FILE *fileA;
fileA=fopen(file_name_for_read,"r");
printf("Enter file name for save...\n");
scanf ("%s", file_name_for_save);
strcat(file_name_for_save,".txt");
FILE *fileB;
fileB=fopen(file_name_for_save,"w");
while(fgets(full_string, 50, fileA) !=NULL)
{
int cnt = 0;
for(i = 2; i < strlen(full_string)-3; i+=3)
{
reduce_string[cnt++] = full_string[i];
}
fprintf(fileB, "%s", reduce_string);
}
fclose(fileA);
fclose(fileB);
}

Print the 5th letter of each word read from a text file

I wanted to find the 5th letter from every word after reading from the text file. I do not know where I am wrong.
After entering the file path, I am getting a pop up window reading
read.c has stopped working.
The code:
#include<stdio.h>
#include<conio.h>
int main(void){
char fname[30];
char ch[]={'\0'};
int i=0;
FILE *fp;
printf("enter file name with path\n");
gets(fname);
fp=fopen(fname,"r");
if(fp==0)
printf("file doesnot exist\n");
else{
printf("File read successfully\n");
do{
ch[i]=getc(fp);
if(feof(fp)){
printf("end of file");
break;
}
else if(ch[i]=='\n'){
putc(ch[4],stdout);
}
i++;
}while(1);
fclose(fp);
}
return 0;
}
I wanted to find the 5th letter from every word
That's not something your code is doing now. It is wrong for various reasons, like
char ch[]={'\0'}; is an array with length 1. with unbound ch[i], you're overrunning the allocated memory creating undefined behaviour.
gets() is very dangerous, it can cause buffer overflow.
getc() reads character-by-character, not word-by-word, so you need to take care of space character (' ') as a delimiter also.
etc.
My suggestion, rewrite your code using the following algorithm.
Allocate a buffer long enough to hold a complete line from the file.
Open the file, check for success.
Read a whole line to the buffer using fgets()
3.1. If fgets() return NULL, you've most probably reached the end of file. End.
3.2. Otherwise, continue to next step.
Tokenize the line using strtok(), using space ' ' as the delimiter. Check the returned token against NULL.
4.1. if token is NULL, go to step 3.
4.2. if token is not NULL, proceeded to next step .
Check strlen() of the returned token (which is the word). if it is more than 4, print the index 4 of the token. (Remember, array index in c is 0 based).
Continue to step 4.
You can use following snippet. With this code you need to know Maximum length of line. This code prints 5th character on each line on each word if its length is 5 or more.. Hope this work for you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 1000
int main()
{
char fname[30];
char myCurLine[MAX_LINE + 1];
char myCurWord[MAX_LINE + 1];
int index,loop;
FILE *fp;
printf("enter file name with path\n");
gets(fname);
fp=fopen(fname,"r");
if(fp==0)
printf("file doesnot exist\n");
else
{
printf("File read successfully\n");
do
{
if(fgets(myCurLine,MAX_LINE,fp) != NULL)
{
index = 0;
for(loop = 0;loop < MAX_LINE; loop++)
{
myCurWord[index] = myCurLine[loop];
index++;
if((myCurLine[loop] == ' ') || (myCurLine[loop] == '\n'))
{
myCurWord[index] = '\0';
index = 0;
if(strlen(myCurWord) > 4)
{
putchar(myCurWord[4]);
}
index = 0;
if(myCurLine[loop] == '\n')
break;
}
}
}
if(feof(fp))
{
break;
}
}while(1);
fclose(fp);
}
return 0;
}
I edited your code because of these reasons:
You don't need to use char array at all, since you're only checking for letters and you can count the letters in every word of the file (which can be checked using spaces) and print when your count reaches 4 (since we start at 0).
Since gets() has no overflow protection, fgets() is more preferred.
fgets(fname, sizeof(fname), stdin);
Another point is you can simplify your do-while loop into one while loop with the condition of breaking if reaching EOF, since your do-while is simply an infinite loop (with condition defined as true or 1) that breaks at EOF (which is checked in a separate if inside the infinite do-while).
while (!feof)
An alternative to char array is to loop until a space ' ' or newline '\n' is found.
I also removed the else from if (fp==0) to avoid too many indents.
I also added ctype.h to check if the 5th letter is really a letter using isalpha().
This is how the word's 5th letter search works:
Loop (outer loop) until end-of-file (EOF).
In each iteration of outer loop, loop (inner loop) until a space ' ' or newline '\n' is found.
If the counter in inner loop reaches 4 (which means 5th letter is reached),
print the current letter,
reset counter to zero,
then break the inner loop.
Applying those edits to your code,
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
int main(void){
char fname[30];
char ch; // changed from array to single char
int i=0;
FILE *fp;
printf("enter file name with path\n");
fgets(fname, sizeof(fname), stdin); // changed from gets()
// removes the \n from the input, or else the file won't be located
// I never encountered a file with newlines in its name.
strtok(fname, "\n");
fp=fopen(fname,"r");
// if file open failed,
// it tells the user that file doesn't exits,
// then ends the program
if (!fp) {
printf("file does not exist\n");
return -1;
}
// loops until end-of-file
while (!feof(fp))
// loops until space or newline or when 5th letter is found
for (i = 0; (ch=getc(fp)) != ' ' && ch != '\n'; i++)
// if 5th character is reached and it is a letter
if (i == 4 && isalpha(ch)) {
putc(ch ,stdout);
// resets letter counter, ends the loop
i = 0;
break;
}
fclose(fp);
return 0;
}
*Note: Words with less than 5 letters will not be included in the output, but you can specify a character or number to indicate that a word has less than 5 letters. (such as 0, -1)
sample read.txt:
reading write love
coder heart
stack overflow
output:
enter file name with path
read.txt
iertkf

Reading a text file in C, stopping at multiple points, breaking it into sections

I have a program that has a text file that is variable in length. It must be capable of being printed in the terminal. My problem is that if the code is too large, part of it becomes inaccessible due to the limited scroll of terminal. I was thinking of having a command executed by a character to continue the lines after a certain point, allowing the user to see what they needed, and scroll if they needed. However the closest I have come is what you see here, which prints the text file one line at a time as you press enter. This is extremely slow and cumbersome. Is there another solution?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE *audit;
audit = fopen("checkout_audit.txt", "r");
char length_of_code[60000];
int ch;
while ((ch = fgetc(audit)) != EOF)
{
fgets(length_of_code, sizeof length_of_code, audit);
fprintf(stdout, length_of_code, audit);
getch();
if (ferror(audit))
{
printf("This is an error message!");
return 13;
}
}
fclose(audit);
return 0;
}
The libraries are included as I tried various methods. Perhaps there is something obvious I am missing, however after looking around I found nothing that suited my needs in C.
You can keep a count of something like num_of_lines and keep incrementing it and when it reaches some number(say 20 lines) then do a getchar() instead of doing it for each line.
Make sure you don't use feof() as already suggested. Just for the purpose of how it can be done I am showing the below snippet.
int num_of_lines = 0;
while(!feof(fp))
{
// fgets();
num_of_lines++;
if(num_of_lines == 20)
{
num_of_lines = 0;
getch();
}
}
Putting the same thing in your code:
int main()
{
FILE *audit;
audit = fopen("checkout_audit.txt", "r");
char length_of_code[60000];
int num_of_lines = 0;
int ch;
while (fgets(length_of_code, sizeof length_of_code, audit) != NULL)
{
fprintf(stdout, length_of_code, audit);
if (ferror(audit))
{
printf("This is an error message!");
return 13;
}
num_of_lines++;
if(num_of_lines == 20)
{
num_of_lines = 0;
getch();
}
}
fclose(audit);
return 0;
}
From the man page of fgets()
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.
Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte is stored after the last character in the buffer.
So char length_of_code[60000]; is not a better option.
Try to set the size of array to optimum value which in most case is 80.
Also as fgets fetches line by line you will have to output line by line untill EOF
EDIT:
1. 2nd argument to fprintf should be the format specifier and not length
2. 3rd arg should be a string and not the file pointer
fprintf(stdout, "%s", length_of_code);
Code Snippet:
while (fgets(length_of_code, sizeof(length_of_code), audit))
{
fprintf(stdout, "%s", length_of_code);
getch();
if (ferror(audit))
{
printf("This is an error message!");
return 13;
}
}

File is not being opened when inputted. C

My issue is when I try to input spath as the first parameter for fopen(); is keeps looping wether the file exists or not. Yet, when i hard code the parameter to my test file it works properly.I am not sure what the issue is, maybe it is the syntax.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char spath[255], dpath[255];
int c;
FILE *sfp, *dfp;
do
{
printf("Please enter a source file:\n");
fgets(spath, sizeof(spath), stdin);
if(strlen(spath) > 253)
{
while((c = getchar()) != '\n' && c != EOF);
}
}while((sfp=fopen(spath,"r")) == NULL);
}
Upon further reading, fgets() has a new line character in the array which messes things up. To fix this use:
for(i = 0 ; i < lenght ; i++)
{
if(array[i] == '\n')
array[i] = '\0' ;
}
This takes away the new line character and insert a terminator character.
Click this link for further information: Open file with user input (string) - C

Resources