Ho to copy text from one file to another in C? - c

I am writing a basic program to copy text to another text file. But in the console window after entering the filename from where text should be taken, the program ends and does not go further. How can I solve this problem?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char filename1, filename2;
FILE *infile;
FILE *outfile;
printf("Enter a data file name:");
scanf("%s", filename1);
infile = fopen("filename1", "r");
printf("Enter a input file name:");
scanf("%s", filename2);
outfile = fopen("filename2", "w");
if (infile == NULL || outfile == NULL) {
printf("Problem in opening files");
exit(0);
}
printf("files opened successfully");
char characters;
do {
characters = getc(infile);
fprintf(outfile,"%s", characters);
printf("%s", characters);
} while (!feof(infile));
fclose(infile);
fclose(outfile);
return 0;
}

There are a few problems with your program:
You are using char variables to hold names of files. These variables should be char arrays or pointers to the first char of some allocated memory.
fopen("filename2", "w") seems wrong. Although, the first argument should be a char *, you are not reading / writing the files you just asked the user to enter.
fprintf(outfile,"%s",characters) - You are using %s to print characters. This will invoke UB.
char characters - The last character of a file, the EOF character is guaranteed to fit in an int. The characters variable should be declared as an int so that it can hold the EOF character.
Here is the program that works:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char filename1[10], filename2[10];
FILE *infile;
FILE *outfile;
printf("Enter a data file name:");
scanf("%s",filename1);
infile = fopen(filename1, "r");
printf("Enter a input file name:");
scanf("%s",filename2);
outfile = fopen(filename2, "w");
if (infile==NULL || outfile==NULL) {
printf("Problem in opening files");
exit(0);
}
printf("files opened successfully");
int characters;
/*do {
characters=getc(infile);
fprintf(outfile,"%s",characters);
printf("%s",characters);
} while(!feof(infile));
*/
while ((characters = getc(infile)) != EOF) {
fprintf(outfile, "%c", characters);
printf("%c", characters);
}
fclose(infile);
fclose(outfile);
return 0;
}

There are a number of issues.
char filename1, filename2;
This only allows filename1 and filename2 to hold a single char - not a C string. You need to reserve memory as a char array. Like:
char filename1[64], filename2[64]; // Allow 63 chars for file name
Then
scanf("%s",filename1);
is really bad as it allows the user to overflow your input buffers. Consider using fgets or at least do:
scanf("%63s",filename1); // Limit user input to 63 chars as the buffer is 64
// The "last" char is for the string termination
Then the loop:
First, characters shall be int so that you can check for EOF. Further, check directly on getc instead of using feof. And don't use %s for printing a single char to the output file - use %c. Like
int characters;
while(1) {
characters=getc(infile);
if (characters == EOF) break; // Break (aka jump out of the loop) on
// end-of-file or errors
fprintf(outfile,"%c",characters); // %c instead of %s
// or use: putc(characters, outfile)
// instead of fprintf
printf("%s",characters);
}

Related

Finding whether a substring exists in a string using user input from STDIN

I have a simply task that I wish to do here is the workflow
User inputs a string which he/she wishes to search exits in a text file
If string is found, code then prints all the lines in a text file where that string exists.
Code terminates/function ends.
Now I managed to get file reading working and all, but the issue happens when I combine user input.
For example, when the user inputs "sushi" it does not print out the lines of string in the text file where the word "sushi" exists.
But if I pass the term manually, it works fine (i.e strstr(lineOfText,"sushi));
Here is my code, what could the issue be
int main() {
word_search();
return 0;
}
int word_search() {
FILE *textFile;
char line[MAX_LINE_LENGTH];
textFile = fopen("PATH TO TEXT FILE", "r");
if (textFile == NULL) {
return 1;
}
printf("Please input word to search:");
char userInput[] = "";
fgets(userInput, 250, stdin);
while (fgets(line, MAX_LINE_LENGTH, textFile)) {
if (strstr(line, userInput) != NULL) {
printf("%s", line);
}
}
fclose(textFile);
return 0;
}
Contents of file
1 Wallaby Way Fenwick
1 Sushi Way Fenwick
1 Wallaby Sushi Way Fenwick
1 Alexandria Way Fenwick
1 Alexandira Sushi Ashfield Way Fenwick
The following
char userInput[] = "";
defines userInput to be an array of size 1. A buffer of size 1 can only hold the empty string.
Attempting to fill this buffer
fgets(userInput,250,stdin);
with up to 250 bytes will surely invoke Undefined Behaviour.
When a newline character is encountered, fgets stores it in the buffer (unless doing so would not leave room for the null-terminating byte).
You must remove the newline character from the query string. See: Removing trailing newline character from fgets() input.
An example program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s FILENAME\n", *argv);
return EXIT_FAILURE;
}
char needle[512];
printf("Enter a string to search for: ");
if (!fgets(needle, sizeof needle, stdin)) {
if (ferror(stdin))
perror("reading stdin");
return EXIT_FAILURE;
}
needle[strcspn(needle, "\n")] = '\0';
FILE *file = fopen(argv[1], "r");
if (!file) {
perror(argv[1]);
return EXIT_FAILURE;
}
char line[1024];
while (fgets(line, sizeof line, file))
if (strstr(line, needle))
printf("%s", line);
fclose(file);
}
Running this program on its own source:
$ ./a.out find.c
Enter a string to search for: need
char needle[512];
if (!fgets(needle, sizeof needle, stdin)) {
needle[strcspn(needle, "\n")] = '\0';
if (strstr(line, needle))

Why are contents of a binary file not being printed in c?

Hello I am writing a program that reads the contents of a binary file and prints them to the screen.
#include <stdio.h>
#include <stdlib.h> // For exit()
int main()
{
FILE *fptr;
char filename[100];
printf("Enter the filename to open \n");
scanf("%s", filename);
// Open file
fptr = fopen(filename, "rb");
if (fptr == NULL)
{
printf("Cannot open file \n");
exit(0);
}
// Read contents from file
fseek(fptr,0L,SEEK_END);
int fsize = ftell(fptr);
fseek(fptr,0L,SEEK_SET);
unsigned char *c = malloc(fsize);
fread(c,fsize,1,fptr);
fclose(fptr);
printf("%s",c);
return 0;
}
but it does not print anything.Can someone explain me why and how should I fix this problem.
What you have attempted is not at all what you wanted to achieve.
Remember printf() formats the data it prints. To be printed properly with the %s formatting, the binary data values must be ASCII values but , of course, they are not.
You should probably attempt to printf() with %d.

C code to write content to a file not working

This is the c code that I wrote to write something to a file. But when I compile it, the process terminates without getting input for the contents. What is the error?
#include <stdio.h>
#include <string.h>
void main()
{
FILE *fp;
char name[20];
char content[100];
printf("Enter file name:\n");
scanf("%s", name);
printf("Enter the content:\n");
gets(content);
fp = fopen(name, "w");
fprintf(fp, "%s", content);
fclose(fp);
}
It blew right past the gets line. Why? Because the scanf family has lots and lots of problems. Avoid them.
Specifically it tends to leave input on the buffer. In this case scanf("%s", name); read in all the text and left a newline on stdin. Then gets dutifully read that newline... and throws it out because that's how gets behaves. We can see this if we print name and content just before gets.
printf("name: '%s'\n", name);
printf("content: '%s'\n", content);
name: 'foo'
content: ''
Then your program dutifully writes nothing to the file.
Instead, use fgets to read entire lines, and sscanf to parse them. This avoids the danger of leaving input on the buffer.
printf("Enter file name:\n");
fgets(name, sizeof(name), stdin);
printf("Enter the content:\n");
fgets(content, sizeof(content), stdin);
fgets does not strip newlines, so you'll have to do that yourself. There's a variety of ways to do it.
void trim( char *string, char to_trim ) {
size_t len = strlen(string);
if( len == 0 ) {
return;
}
size_t last_idx = len -1;
if( string[last_idx] == to_trim ) {
string[last_idx] = '\0';
}
}
I prefer this approach because it only removes the newline if it's the final character.
Finally, always check your file operations. You're not checking if the fopen succeeded. If it fails for whatever reason you'll get another mysterious error. In my case the name I was using for testing already existed as a directory.
#include <string.h> // for strerror
#include <errno.h> // for errno
fp = fopen(name, "w");
if( fp == NULL ) {
fprintf(stderr, "Could not open '%s' for writing: %s.\n", name, strerror(errno));
return 1;
}

Writing String to text file in C leaves bits of characters off

My goal is to be able to write a string to a file and have the whole thing show up, and not just part of it. The problem is that when i check into my text file there is a few charters left off of the string that i typed in.
Here is My code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp = fopen("file.txt", "w");
if (fp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
char comment[100];
fp=fopen("/home/matthew/Desktop/BBE.txt","w");
printf("Enter, String: ");
scanf("%s", &comment);
fgets(comment, sizeof comment, stdin);
fputs(comment,fp);
}
And the input that i want in my text file is this:
Enter, String: Hello World
But when i check my text file i get this:
World
I am missing a word here and have no idea why, please help.
Get rid of the scanf, as it is reading in the first word of your input, so your code looks like this:
char comment[100];
fp=fopen("/home/matthew/Desktop/BBE.txt","w");
printf("Enter, String: ");
fgets(comment, sizeof comment, stdin);
fputs(comment,fp);
You are reading the input from the user using both fgets and scanf. You don't need both. Also, in your scanf, you are passing the address of the address of the first element of the character array instead of just the address of the first element (use 'comment' instead of '&comment' in your scanf). You are also not closing the File after write. Try following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp = fopen("/home/matthew/Desktop/BBE.txt", "w");
if (fp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
char comment[100];
fp=fopen("file.txt","w");
printf("Enter, String: ");
scanf("%s", comment); //Don't pass &comment. Just pass 'comment' - the addr of zeroth element.
//fgets(comment, sizeof comment, stdin);
fputs(comment,fp);
fclose(fp);
}
Why are you using two files here when you've to write the input from stdin in one of the file? Below piece of code will help you get the desired output. Better to use gets() here instead of fgets() as you're not reading input from file. Also, don't forget to close the files when you're done. Hope this helps!!
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char comment[100] = {0};
fp=fopen("tempfile.txt","w");
if (fp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
printf("Enter String: ");
gets(comment);
fwrite(comment, sizeof(comment), 1, fp) ;
fclose(fp);
return 0;
}

fprintf() on a new line of a file

How i can make a new line at the end of a file to fprintf() user inputed text?
My code right now is this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int lines;
int number;
FILE *fp;
printf("Insert random number: ");
scanf("%d", &number);
fp = fopen("textfile.txt", "r");
char ch;
while((ch=fgetc(fp))!=EOF)
{
if (ch=='\n') {
lines++;
}
}
fclose(fp);
fopen("textfile.txt", "ab");
fseek(fp, lines, SEEK_SET);
fprintf(fp,"%d", number);
fclose(fp);
}
You just need to add a '\n' to the fprintf() like this
fprintf(fp,"\n%d", number)
/* ^ */
but you also need a lot of error checking, for instance fopen() returns NULL when it fails to open the file.
Your code is actually very broken, you count the lines in the file opened with "r", i.e. for reading, then you call fopen() with "ab" but discard the return value, you then fseek() the number of lines, and fseek() is for the number of characters not lines, then you write to the closed fp pointer, because
fopen("textfile.txt", "ab"); /* you don't assign the return value anywhere */
fseek(fp, lines, SEEK_SET); /* this is the same pointer you `fclosed()' */
/* ^ this will not seek to the end of the file */
fprintf(fp,"%d", number); /* here `fp' is still invalid */
Test this
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file;
const char *filename = "textfile.txt";
printf("Insert a number: ");
if (scanf("%d", &number) != 1)
{
fpritnf(stderr, "invalid input, expected a number\n");
return -1;
}
file = fopen(filename, "a");
if (file == NULL)
{
fprintf(stderr, "cannot open %s for appending\n", filename);
return -1;
}
fprintf(file, "\n%d", number);
fclose(file);
return 0;
}
You don't need to fseek() if you open with "a" because new content is appended to the end of the file, you need a '\n' before the user input if there was no '\n' in the file or if you want to force the new value in a new line.
You don't need the "b" in the mode string, because you are writing text to the file, and on some platforms the file will have issues when you open it in a text editor.

Resources