Write user input to a file and then read it - c

I have to recieve user input with this style:
U word word2 word3
U word word2 word3
R word
R word
X
I want to write it to a file and then read what was written but the program is in a endless loop, and the file is being created but its empty, it seems to me the program never leaves the while loop that writes to a file for some reason.
void write_to_file(FILE *fp){
char buffer[37];
while(fgets(buffer, 37, stdin)){
fprintf(fp, "%s", buffer);
}
fclose(fp);
}
void read_from_file(FILE *fp){
char buffer[37];
char tipo;
char input_a[6];
char input_b[26];
while(fgets(buffer, 37, fp)) {
sscanf(buffer, "%c %s %[^\n]", &tipo, input_a, input_b);
switch(tipo) {
case 'U' :
// do stuff
break;
case 'R' :
// do stuff
break;
case 'X' :
exit(0);
break;
default :
printf("Invalid Operation\n");
}
}
}
int main(){
FILE *fp = fopen("input.txt","a+");
write_to_file(fp);
read_from_file(fp);
return 0;
}
I opened the file with a+ because in case the file already exists i want to write after the last line
Thanks in advance.

the program is in a endless loop ? Its because of below while() loop
while(fgets(buffer, 37, stdin)) {
}
As man 3 fgets says
fgets() return s on success, and NULL on error or when end
of file occurs while no characters have been read.
you can end this loop by hitting ctrl+d but if you press ctrl+d your main process a.out gets terminated. One way to solve this problem is give one extra \n or ENTER as input at last and then chen the return value of fgets().
Here is the sample code
void write_to_file(FILE *fp){
char buffer[37], *ptr = NULL;
while((ptr = fgets(buffer, 37, stdin))!=NULL) { /* It return NULL upon reaching EOF */
if(*ptr != '\n') { /* at last user enters \n, compare here, if true , break the loop */
fprintf(fp, "%s", buffer);
}
else
break;
}
fclose(fp);
}

Related

Print whole line which starts from given letter

I'm trying to print lines which starts from given letter to second file but it prints only 1 line and then stops, even if there are more lines which starts with given letter. How to fix it ?
#include <stdio.h>
#include <string.h>
int main()
{
FILE* f = fopen("story.txt","r");
char usr;
printf("enter letter: ");
scanf(" %c",&usr);
FILE* f2=fopen("letter.txt","a+");
char buffer[255];
while(fscanf(f, "%[^\n]s", buffer)==1)
if (*buffer == usr)
fprintf(f2, "%s\n", buffer);
return 0;
}
The second time through the loop, fscanf(f, "%[^\n]s", buffer) fails to scan anything because the previous call left the \n character in the buffer. This can't get past that.
Use fgets() instead of fscanf() to read a whole line.
char buffer[255];
while(fgets(buffer, sizeof buffer, f))
if (buffer[0] == usr)
fprintf(f2, "%s", buffer);
I would not use fscanf to read line of text.
//fi - input file
//fo - output file
int copyLines(FILE *fi, FILE *fo, char c)
{
char line[256];
if(fi && fo)
{
while(fgets(line, sizeof(line), fi))
{
if(*line = c)
if(fputs(line, fo) == EOF) return EOF;
}
}
return 0;
}
For starters the format string in the call of fscanf is incorrect
while(fscanf(f, "%[^\n]s", buffer)==1)
^^^
At least you should remove the letter s.
Another problem is that after such a call of fscanf the new line character '\n' is not read. So the next call of fscanf reads an empty string.
It is better to use another C function fgtes. But you need to use it with a caution.
In general a string stored in the input file can be greater than the size of the array buffer.
That means that you need to read some strings in the input file using more than one call of fgets. Otherwise the output file will be formed incorrectly.
The loop can look the following way
int success = 1;
do
{
success = fgets( buffer, sizeof( buffer ), f ) != NULL;
if ( success )
{
int target = *buffer == usr;
if ( target ) fprintf( f2, "%s", buffer );
while ( success && !strchr( buffer, '\n' ) )
{
success = fgets( buffer, sizeof( buffer ), f ) != NULL;
if ( success && target ) fprintf( f2, "%s", buffer );
}
}
} while ( success );

How can I copy some strings from file to another using c programming

I have this code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* ptr = fopen("data.txt","r");
char filename[100];
if (ptr==NULL)
{
printf("no such file.");
return 0;
}
char buf[100];
while (fscanf(ptr,"%*s %*s %s ",buf)==1)
printf("%s\n", buf);
printf("Create a file \n");
scanf("%s", filename);
fptr2 = fopen(filename, "w");
if (fptr2 == NULL)
{
printf("Cannot open file %s \n", filename);
exit(0);
}
c = fgetc(fptr1);
while (c != EOF)
{
fputc(c, fptr2);
c = fgetc(fptr1);
}
printf("\nContents copied to %s", filename);
fclose(fptr1);
fclose(fptr2);
return 0;
}
}
It coppies full content from one file to another. I need to copy only strings that have 5 as the last character (3 column)
For example Data.txt looks like that:
Alex 10B 4
John 10A 3
Kate 10C 5
In file that I will create during execution has to be coppied only Kate 10C 5 string. I've been trying for hours but I don't know how to do this. Can you help me?
In the end of each line there is a newline character, (\n) you can use that to read line by line and copy only the ones that you want:
FILE* dest = fopen("out.txt", "w+"); // supressed null check for simplicity
char buf[100];
char* char_to_find;
// parse line by line
while (fscanf(ptr, " %99[^\n]", buf) == 1){
char_to_find = buf;
// reach the end of the line
while(*char_to_find){
char_to_find++;
}
//move one back
char_to_find--;
// if it's 5 save, if not move on
if(*char_to_find == '5' && *(char_to_find - 1) == ' '){
fputs(buf, dest);
}
}
Live demo
The problem is that the function call
while (fscanf(ptr,"%*s %*s %s ",buf)==1)
consumes the input from the input stream, so that it is no longer available for copying. You are only saving the contents of the last field, but all other data is lost.
I suggest that you read one line at a time into a memory buffer, by calling the function fgets in a loop. That way, you will process one line of input per loop iteration, and will be saving the contents of the entire line.
In every loop iteration, you can use sscanf on this memory buffer to determine whether the third field has the desired value, and if it does, then you copy the entire line to the output file. Otherwise, you do nothing and proceed to the next line (i.e. the next loop iteration).
char line[100];
//process one line of input per loop iteration
while ( fgets( line, sizeof line, input_file ) != NULL )
{
char third_field[20];
if (
//third field was successfully extracted
sscanf( line, "%*s%*s%19s", third_field ) == 1
&&
//third field contains the string "5"
strcmp( third_field, "5" ) == 0
)
{
//copy entire line to output file
fputs( line, output_file );
}
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* ptr = fopen("data.txt","r");
char filename[100];
if (ptr==NULL)
{
printf("no such file.");
return 0;
}
printf("Create a file \n");
scanf("%s", filename);
FILE* dest = fopen(filename, "w+"); // check for null like above
char buf[100];
char* char_to_find;
while (fscanf(ptr,"%99[^\n] ", buf) == 1){
char_to_find = buf;
while(*char_to_find != 0){
char_to_find++;
}
char_to_find--;
if(*char_to_find == '5'){
printf("%s\n", buf); // test ptint
fputs(buf, dest);
}
}
}

how to read and write beyond the defined characters in fgets() function

I am working on a assignment:
Open a text file and print its contents in command window, ask the user to
replace the text from the text file to be written and save the text
file.
When I set the maximum character size to 256,it works but when I give 20 it doesn't. Is there a way to overcome this problem by printing the characters beyond the defined limit?
I have used fgets() function.
#include <stdio.h>
#include <string.h>
#define MAX 20
int main(){
FILE *fptr1, *fptr2;
int lno, linectr = 1;
char str[MAX],fname[MAX];
char newln[MAX], temp[] = "temp.txt";
printf("\n\n Replace a specific line in a text file with a new text :\n");
printf(" Input the file name to be opened : ");
fgets(fname, MAX, stdin);
fname[strlen(fname) - 1] = '\0';
fptr1 = fopen(fname, "r");
if (!fptr1)
{
printf("Unable to open the input file!!\n");
return 0;
}
fptr2 = fopen(temp, "w");
if (!fptr2)
{
printf("Unable to open a temporary file to write!!\n");
fclose(fptr1);
return 0;
}
printf(" Input the content of the new line : ");
fgets(newln, MAX, stdin);
fgets(str, MAX, stdin);
printf(" Input the line no you want to replace : ");
scanf("%d", &lno);
lno++;
while (!feof(fptr1))
{
strcpy(str, "\0");
fgets(str, MAX, fptr1);
if (!feof(fptr1))
{
linectr++;
if (linectr != lno)
{
fprintf(fptr2, "%s", str);
}
else
{
fprintf(fptr2, "%s", newln);
}
}
}
fclose(fptr1);
fclose(fptr2);
remove(fname);
rename(temp, fname);
printf(" Replacement did successfully\n");
return 0;
}
I'm assuming you are asking how to read a 100 char long line into a 20 char sized buffer.
Well, obviously the whole line does not fit into the buffer. You need to read in chunks. You know you've read the last chunk when the buffer contains a newline (or EOF is reached)...
if (!fgets(str, MAX, fptr1)) /* EOF detected */;
//let's see if we got a partial line
size_t len = strlen(str); // note: len != 0 for text files
if (str[len - 1] == '\n') {
// full line
// do the comparison or whatever
} else {
// fgets got first chunk
// read rest of line and ignore it
for (;;) {
int ch = fgetc(fptr1);
if (ch == EOF) /* EOF detected */;
if (ch == '\n') break; // full line read, ready for next one
}
}

Reading a text file line by line in c

I try to read the file that I wrote the first three line, line by line. However, it enters infinity loop. How can I stop it at the end of the file?
while(fscanf(infile, "%[^\n]", ch) != EOF)
printf("%s", ch);
Tiffany;Evans Smith;F;22/01/1989;
Alex;Williams;M;23/06/1988;
Clay;Bristol;F;30/12/1989;
There are multiple ways of reading a text file line by line. Hopefully, the following code answers your question.
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *infile;
char data[BUFSIZ];
infile=fopen("filename","r");
while((fgets(data,BUFSIZ,infile)!=NULL))
puts(data);
}
if you want to use fscanf, you can use this code :
int ret;
while(ret = fscanf(infile,"%s",str))
{
if (ret == EOF)
break;
if(ret >0 )
{
cout << str <<endl;
}
else
{
break;
}
}
here, int ret is:
EOF, if the pointer is reached end of file.
0, if no input matched with the variable
>0, number of matched variables with the file input

How do I store a text file into an array in C

I am trying to open a text file inputted by the user and read this text file but print the text file 60 characters at a time so I think in order for me to do this I need to store the text into an array and if it is over 60 characters on a line it should start on a new line. However, when I run the code below an error message shows up saying : C^#
#include <stdio.h>
#include <stdlib.h>
int main()
{
char arr[];
arr[count] = '\0';
char ch, file_name[25];
FILE *fp;
printf("Enter file name: \n");
gets(file_name);
fp = fopen(file_name,"r"); // reading the file
if( fp == NULL )
{
perror("This file does not exist\n"); //if file cannot be found print error message
exit(EXIT_FAILURE);
}
printf("The contents of %s file are :\n", file_name);
while( ( ch = fgetc(fp) ) != EOF ){
arr[count] = ch;
count++;
printf("%s", arr);}
fclose(fp);
return 0;
}
char arr[]; is invalid.you need to specify a size.
array[count] = '\0'; : count is uninitialized.
gets(file_name); : gets is deprecated and dangerous.use another function like scanf.
Try the following code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int ch , count = 0;
char file_name[25];
FILE *fp;
printf("Enter file name: \n");
scanf(" %24s",file_name);
fp = fopen(file_name,"r"); // reading the file
if( fp == NULL )
{
perror("This file does not exist\n"); //if file cannot be found print error message
exit(EXIT_FAILURE);
}
fseek(fp, 0L, SEEK_END);
long sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
char arr[sz];
while( ( ch = fgetc(fp) ) != EOF )
{
if( count < sz )
{
arr[count] = ch;
count++;
}
}
arr[sz] = '\0';
printf("The contents of %s file are :\n", file_name);
printf("arr : %s\n",arr);
fclose(fp);
return 0;
}
fgetc always reads the next character until EOF. use fgets() instead:
char *fgets(char *s, int size, FILE *stream)
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 (aq\0aq) is stored after the last character in the
buffer.
1) your while loop is not properly delimited. In the absence of a { } block, the instruction arr[count] = ch; is the only repeted one.
I suppose it should include the incrementation of count too
while( ( ch = fgetc(fp) ) != EOF )
{
arr[count] = ch;
count++;
....
}
among other things (testing the counter etc).
2) there's no imperative need to read and store in an array. It is perfectly possible to transfer each character as soon as it is read, and add a line break when needed (new line, limit of 60 exceeded).
Three problems:
The variable count is not initialized, so it's value is indeterminate and using it will lead to undefined behavior.
The call printf(arr) treats arr as a string but arr is not terminated which again leads to undefined behavior.
The increment of count is outside the loop.
To solve the two first problems you must first initialize count to zero, then you must terminate the string after the loop:
arr[count] = '\0';
However, your printf(arr) call is still very problematic, what if the user enters some printf formatting codes, what will happen then? That's why you should never call printf with a user-provided input string, instead simply do
printf("%s", arr);
You also have a very big problem if the contents of the file you read is longer than 59 characters, and then you will overflow the array.

Resources