Cannot copy one file to another file - c

While im studying C from a old book (that might be the problem), i wrote the code to copy the content of one file to another one.
But somehow, the program stops working. I would appreciate some help.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
FILE *fin, *fout; //Pointers to the files
int ch;
if (argc!=3) //Just checking if the user inserted the correct information
{
printf("\nCorrect mode: Program name, file1 -> file2 \n\n");
exit(1);
}
fin=fopen(argv[1], "rb");
if (fin==NULL) //Checking if the file exists
{
printf("\n\nERROR!\n\nThe file you're trying to open does not exist or it cannot be opened.\n\n");
exit(2);
}
if ((fout=fopen(argv[2], "wb"))==NULL) // If it cannot create a file
{
printf("\n\nERROR!\n\nImpossible to create the file %s\n\n", argv[2]);
exit(3);
}
while ((ch=fgetc(fin))!=EOF)
fputs(ch, fout);
fclose(fin);
fclose(fout);
}

You are using fputs to write the characters. It is used for strings (arrays of char). Instead use fputc.

Related

File not reading

I am trying to run a simple test to read and print a file to console. I have my "main.c" file and "myfile.txt" in the same folder on my desktop (Mac). However, when running the program I receive "No such file or directory." I tried changing the address to everything I can think of... Can someone please point out what I am doing wrong? My apologies I am new to this and have hit a wall.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE * file;
char str [256];
file = fopen("myfile.txt", "r");
if (NULL == file)
{
perror("Error when opening file!");
return -1;
}
if(fgets(str, 10, file) != NULL)
{
printf("%s", &str);
}
fclose(file);
}
I was expecting to print the first 10 chars of the txt file into the console. Instead I received "No such file or directory."

read a text file, make some trivial transformation character by character (swapping the case of all letters), write result to text file

I have to read a text file, make some trivial transformation character by character (swapping the case of all letters), write results to the text files. I wrote this code, but it's not working. Please guide me in this regard. Thanks for in Advance
#include <stdio.h>
#include <stdlib.h>
int main() {
char c[1000];
char x[100];
char var;
int i;
FILE *fptr;
if ((fptr = fopen("text.txt", "r")) == NULL) {
printf("Error! opening file");
// Program exits if file pointer returns NULL...
exit(1);
}
// reads text until a newline is encountered...
fscanf(fptr, "%[^\n]", c);
printf("Data from the file:\n%s", c);
// Convert the file to upper case....
for( i=0;i<= strlen(c);i++){
if(c[i]>=65&&c[i]<=90)
c[i]=c[i]+32;
}
fptr = fopen("program.txt","w");
fprintf(fptr,"%[^\n]",c);
fclose(fptr);
return 0;
}
Edit: added #include <stdlib.h>, removed static describing main()
My proposition, based on example of copying a file given at my uni.
I used toupper() from ctype.h, if you don't want to use it you can just add 32 under condition similarly to your solution
Note: there could be char c instead of int c. (In the original version it actually was char; I changed it because if you look at the headers in the docs of all functions dealing with c, they all take/return int, not char; in your version it would matter more as you keep an array, in my program it changes pretty much nothing – int is just my preferred practice).
Note2: I actually never delved into the difference between "w"/"r" (write/read) and "wb"/"rb" (write/read binary). The code seems to work either way.
(I think there is no big difference when the files are text files anyway, for further assurance that both versions work, note that the code uses feof() to handle EOF)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
FILE *from, *to;
int c;//could be char
/* opening the source file */
if ((from = fopen("text.txt", "rb")) == NULL) {
printf("no such source file\n");
exit(1);
}
/* opening the target file */
if ((to = fopen("program.txt", "wb")) == NULL) {
printf("error while opening target file\n");
exit(1);
}
while (!feof(from)) {
c = fgetc(from);
if (ferror(from)) {
printf("error while reading from the source file\n");
exit(1);
}
if (!feof(from)) {//we avoid writing EOF
fputc(toupper(c), to);
if (ferror(to)) {
printf("error while writing to the target file\n");
exit(1);
}
}
}
if (fclose(from) == EOF) {
printf("error while closing...\n");
exit(1);
}
if (fclose(to) == EOF) {
printf("error while closing...\n");
exit(1);
}
return 0;
}
For a version taking arguments from command line (works on windows too) replace the beginning of main with
int main(int argc, char *argv[]) {
FILE *from, *to;
char c;
/* checking the number of arguments in the command line */
if (argc != 3) {
printf("usage: name_of_executable_of_this_main <f1> <f2>\n");//name_of_exe could be copy_to_upper, for example; change adequately
exit(1);
}
/* opening the source file */
if ((from = fopen(argv[1], "rb")) == NULL) {
printf("no such source file\n");
exit(1);
}
/* opening the target file */
if ((to = fopen(argv[2], "wb")) == NULL) {
printf("error while opening the target file\n");
exit(1);
}
I don't know how to code in that language(i think it's C++), but basically want you should be doing is a for loop to iterate through every character in the string. In Python it would look like:
x = open("text.txt", "r")
y = open("new text.txt","w")
z = ""
for char in x:
z += char.upper()
y.write(z)
I hope I was able to give an idea of how to solve your problem. I'm a newbie as well, but in Python.

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 - How to extract specific comment lines from a code file

I want to write a code to extract todo task list from a code file.It's basically scanning a code file and detecting lines that include "TODO" string and then writing those lines into a text file.
So far my my code is like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE* f;
char line[200];
f = fopen("someFile.c", "r");
char c;
char str;
while(!feof(f)){
fgets(line,sizeof(line),f);
if(strstr(line, "TODO") != NULL)//Extracts every line with TODO
{
c=fgetc(f);//c = lines with TODO
}
}
fclose(f);
f= fopen("todoListFile.txt","w");
while(!feof(f))
{
fputs(c,f);//Writing the content of the c in to the text file.
}
fclose(f);
return 0;
}
When I run this code it crashes after 1-2 seconds.
My mistake is probably at the second part which is getting those "TODO" lines and writing down those to the text lines. But I'm pretty stuck at that part and don't know what to do.
Note: Content of someFile.c is basically some comment lines with "// TODO :"
The specification pretty much indicates that you have to open two files, one for reading, one for writing. As you read a line from the input file, if that line contains TODO, you need to write that line to the output file. That leads to the straight-forward code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char file1[] = "someFile.c";
char file2[] = "todoListFile.txt";
FILE *fp1 = fopen(file1, "r");
if (fp1 == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", file1);
return 1;
}
FILE *fp2 = fopen(file2, "w");
if (fp2 == NULL)
{
fprintf(stderr, "Failed to open file %s for writing\n", file2);
return 1;
}
char line[200];
while (fgets(line, sizeof(line), fp1) != 0)
{
if (strstr(line, "TODO") != NULL)
fputs(line, fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}
Note that it checks that the files were opened successfully, and reports the file name if it failed, and exits with a non-zero status (you could add <stdlib.h> and use EXIT_FAILURE if you prefer).
When run on (a copy of) its own source, it leaves the todoListFile.txt containing one line:
if (strstr(line, "TODO") != NULL)
Simple modifications of the program would:
Write to standard output instead a fixed name file.
Take command line arguments and process all the input files named.
Read standard input if no input files are named.
Increase the line length. 200 is better than 80, but lines can be longer than that. I tend to use 4096 as a line length unless there's a reason to allow longer lines.

fwrite() appends instead of write C

I have to write a program witch reads from a file received by line and then it overwrites it with the read words uppercased.
This is my code
void toUpperCase(char* string) {
int i=0;
while(string[i])
{
string[i]=toupper(string[i]);
i++;
} }
int main(int argc, char** argv) {
if(argc==1)
{
puts("Error: INSERT PATH");
exit(0);
}
char* file=argv[1];
FILE* fd=fopen(file,"r+");
if(fd<0)
{
perror("Error opening file: ");
exit(0);
}
char buffer[30][30];
int i=0;
while(!feof(fd))
{
fscanf(fd,"%s",buffer[i]);
i++;
}
int j=0;
for(j=0; j<i; j++)
{
toUpperCase(buffer[j]);
fwrite(buffer[j],strlen(buffer[j]),1,fd);
}
fclose(fd);
return 0; }
but this program appends the words contained in buffer[][] instead of overwriting the file.
If the file contain was something like pippo pluto foo then, after the execution is pippo pluto fooPIPPOPLUTOFOO instead of PIPPO PLUTO FOO.
Where am i wrong? Thank you
You have to reset the file position indicator using fseek, as fscanf will advance it. Something like
fseek(fd, length_of_read_string, SEEK_CUR);
This allows you to read the file in chunks, but it will be tricky to get right. Or of course reset it to the file start because you read everything in 1 go:
fseek(fd, 0L, SEEK_SET);
I strongly recommend writing the modified data into a new file, and then after the program has run, delete the initial file and rename the new one. That will also take care of another issue with your program, you are reading the entire file into memory before handling it.
If you want to do in-place translation that doesn't change lengths, you can open the source file in two streams and then do read-chunk, write-chunk in lockstep. That has the advantage of being super-easy to convert to a non-in-place version that will work with nonseekable files too (stdin/stdout, pipes, and sockets).
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h> //toupper
inline void upcaseStr(char* str){
for(;*str;str++) { *str=toupper(*str); }
}
int upcaseStream(FILE* in, FILE* out){
char buf[BUFSIZ]; //BUFSIZ is an implementation-defined constant for an optimal buffer size
while(fgets(buf, BUFSIZ, in)){
upcaseStr(buf);
if(fputs(buf, out) == EOF){ return 1; }
}
if(!feof){ return 1; }
return 0;
}
int main(int argc, char **argv)
{
//default in and out
FILE* in = stdin;
FILE* out = stdout;
if(argc == 2) {
in = fopen(argv[1], "r"); //for reading
out = fopen(argv[1], "r+"); //for writing (and reading) starting at the beginning
if(!(in && out)){
fprintf(stderr, "Error opening file %s for reading and writing: %s\n", argv[1], strerror(errno));
}
}
return upcaseStream(in, out);
}
If you do use the in-place version, then in the unlikely event that the if(fputs(buf, out) == EOF){ return 1; } line should return, you're screwed unless you have a backup copy of the file. :)
Note:
You shouldn't name your FILE pointers fd because C people will tend to think you mean "file descriptor". FILE is a struct around a file descriptor. A file descriptor is just an int that you can use for FILE access with the raw system calls. FILE streams are an abstraction layer on top of file descriptors--they aren't file descriptors.
As you read from the file, its internal position indicator gets moved. Once you start writing, you start writing from that position on, which happens to be at the end of the file. So you effectively append the data to the file.
Rewind the handle to reset the position indicator before writing into the file:
rewind(fp);
On a side note, you are reading the file incorrectly:
while(!feof(fd))
{
fscanf(fd,"%s",buffer[i]);
i++;
}
When you reach the end of the file, fscanf will return an error and not read anything, yet you still increment variable i, as if the read was successful. And then you check feof() for end-of-file, but i was already incremented.
Check feof() and return of fscanf() immediately after calling fscanf():
while(1)
{
int read = fscanf(fd,"%s",buffer[i]);
if( read != 1 )
//handle invalid read
if( feof(fd) )
break;
i++;
}
Think about what happens if the string is longer than 29 characters and/or the file contains more than 30 strings. char buffer[30][30];
Welcome to StackOverflow!
Reopening the stream with fopen with the "w" parameter:
fd=fopen(file, "w");
It opens the file and if there are any contents in the file, it clears them.

Resources