Extra character at end while copying? - c

This is making me nuts I am trying to make a simple program to copy any type of file using the following code but the result I get is unexpected (one or two extra characters at the end of copied file?). For instance if my original file has This is an example the copied file contains This is an exampleÿ
CODE
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp,*fpp;
char pbuff, fname[32];
int i;
printf(" FILE NAME TO OPEN : ");
scanf(" %32s", fname);
fp = fopen(fname, "rb");
fpp = fopen("file", "wb");
if(fp==NULL)
{
printf("NO SUCH FILE. EXITING NOW.");
getch();
exit(1);
}
while(!feof(fp))
{
pbuff = fgetc(fp);
fputc(pbuff, fpp);
}
printf("SUCCESSFULLY CREATED!");
fclose(fp);
fclose(fpp);
getch();
return(0);
}
Can anyone help me out with this one? I will be really very thankful.

The reason is that feof (like most end-of-file indicators in most languages/environments) is only set AFTER the end-of-file has been reached. Since you write the character and only then check the EOF status, you're writing 1 too many characters. fgetc's return value is a predefined EOF if the end-of-file was reached during the call.
You could solve that in 1 of 2 ways:
while(true)
{
pbuff = fgetc(fp);
if(feof(fp))
break;
fputc(pbuff, fpp);
}
Or: (edit as melpomene correctly noticed!)
// Change pbuff to type int in the declartion, and then...
while(true)
{
pbuff = fgetc(fp);
if(EOF == pbuff)
break;
fputc(pbuff, fpp);
}

Related

Printing the first 10 line of a file in C

I'm new to programming in C. And I'm trying to print the first 10 lines of a text file. When I run my program with a text file containing 11 lines of text, only the first line is displayed. I'm not sure why it does that, but I suspect there is something wrong in my while loop. Can someone please help me?
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *myfile;
char content;
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL){
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
content = fgetc(myfile);
while (content != EOF){
max++;
if (max > 10)
break;
printf ("%c", content);
content = fgetc(myfile);
}
fclose(myfile);
return 0;
}
You have been already advised to use fgets. However, if your file has lines of unknown length, you may still want to use fgetc. Just make sure you count only newlines, not all characters:
int max = 0;
int content;
while ((content = fgetc(myfile)) != EOF && max < 10){
if (content == '\n') max++;
putchar(content);
}
fgetc() returns the next character in the file, not the next line. You probably want to use fgets() instead, which reads up to the next newline character into a buffer. Your code should probably end up with something like:
// allocate 1K for a buffer to read
char *buff = malloc(1024);
// iterate through file until we are out of data or we read 10 lines
while(fgets(buff, 1024, myfile) != NULL && max++ < 10) {
printf("%s\n", buff);
}
free(buff);
// close your file, finish up...
Read more about fgets() here: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
fgetc function reads the next character not the next ine. for reading the number of lines you should use fgets function. this function reads the full string till the end of the one line and stores it in a string.
your code Shuld be as:-
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *myfile;
char content[200];
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL)
{
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
fgets(content, 200, myfile);
while (content != EOF)
{
max++;
if (max > 10)
break;
printf("%s", content);
fgets(content, 200, myfile);
}
fclose(myfile);
return 0;
}

Ho to copy text from one file to another in 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);
}

fopen give me a segementation fault

I'm trying to open the output_voice_capture.txt but it gives me a segementation fault, not only the file exists but it has read privilege.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fPtr;
char ch;
/*
* Open file in r (read) mode.
*/
printf("Opening file ......\n");
fPtr = fopen("/flash/etc/output_voice_capture.txt", "r");
if(fPtr == NULL)
{
/* Unable to open file hence exit */
printf("Unable to open file.\n");
printf("Please check whether file exists and you have read privilege.\n");
exit(EXIT_FAILURE);
}
/* File open success message */
printf("File opened successfully. Reading file contents character by character.\n");
do
{ printf("Read single character from file ......\n");
/* Read single character from file */
ch = fgetc(fPtr);
/* Print character read code ASCII on console */
printf ("%d \n", ch);
} while(ch != EOF); /* Repeat this if last read character is not EOF */
printf("Closing file ......\n");
fclose(fPtr);
return 0;
}
I am using minicom which contains all the bin that I can use , the problem is that when I use linux terminal and a simple .txt test file the code works just fine.
As Zaboj Campula already said in his comment EOF is defined as an integer of -1. On some systems a char is a value from 0..255, on others from -127..128. To avoid any problems one should use the feof() function (link) to check the end of the stream. This might be the source of your problem due to the different sizes of char and int.
Your code will print "File opened successfully. Reading file contents character by character." for each character read.
Leave functions only at one place: at the end. This makes your code much more readable
When parts of your code depend on something, enclose it with an error check.
Try this code:
int main() {
FILE * fPtr;
char ch;
int result = 0;
printf("Opening file ......\n");
if (!(fPtr = fopen("/flash/etc/output_voice_capture.txt", "r")) {
printf("Unable to open file.\n");
printf("Please check whether file exists and you have read privilege.\n");
result = EXIT_FAILURE;
} else {
printf("File opened successfully. Reading file contents character by character.\n");
while (EOF != (ch = fgetc(fPtr))) {
printf ("%d \n", ch);
}
fclose(fPtr);
}
return result;
}

How to take first row from this list of text?

I have a list of columns containing text but I just to fetch first upper row from this list. How to do that?
#include <stdio.h>
int main()
{
FILE *fr;
char c;
fr = fopen("prog.txt", "r");
while( c != EOF)
{
c = fgetc(fr); /* read from file*/
printf("%c",c); /* display on screen*/
}
fclose(fr);
return 0;
}
Your stop condition is EOF, everything will be read to the end of the file, what you need is to read till newline character is found, furthermore EOF (-1) should be compared with int type.
You'll need something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fr;
int c;
if(!(fr = fopen("prog.txt", "r"))){ //check file opening
perror("File error");
return EXIT_FAILURE;
}
while ((c = fgetc(fr)) != EOF && c != '\n')
{
printf("%c",c); /* display on screen*/
}
fclose(fr);
return EXIT_SUCCESS;
}
This is respecting your code reading the line char by char, you also have the library functions that allow you to read whole line, like fgets() for a portable piece of code, or getline() if you are not on Windows, alternatively download a portable version, and, of course you can make your own like this one or this one.
For whatever it's worth, here's an example that uses getline
#include <stdio.h>
int main()
{
FILE *fr;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if (!(fr = fopen("prog.txt", "r"))) {
perror("Unable to open file");
return 1;
}
nread = getline(&line, &len, fr);
printf("line: %s, nread: %ld\n", line, nread);
fclose(fr);
return 0;
}
Some notes:
getline() can automatically allocate your read buffer, if you wish.
getline() returns the end of line delimiter. You can always strip it off, if you don't want it.
It's ALWAYS a good idea to check the status of I/O calls like "fopen()".
just replace EOF as '\n'(new line char). Than your code will read until reaching the new line. Here is what it looks like:
#include <stdio.h>
int main()
{
FILE *fr;
char c = ' ';
fr = fopen("prog.txt", "r");
while(c != EOF && c != '\n')
{
c = fgetc(fr); /* read from file*/
if(c != EOF){
printf("%c",c); /* display on screen*/
}
}
fclose(fr);
return 0;
}
I have not tested it yet but probably work. Please let me know if there is some problem with the code i will edit it.
Edit1:char c; in line 5 is initialized as ' ' for dealing with UB.
Edit2:adding condition (c != EOF) to while loop in line 7, for not giving reason to infinite loop.
Edit3:adding if statement to line 10 for not printing EOF which can be reason for odd results.

Replacing specific text of a file in C

Alright, so basically what I have to do is change all the numbers of a text file to dollar sign, I know how to scan for the specific character but I am stuck on how to replace that specific character with dollar sign. I don't want to use fseek or any library commands, how do I proceed and why isn't my code working?
#include<stdio.h>
main()
{
FILE* fptr;
char filename[50];
char string[100];
int i;
printf("Enter the name of the file to be opened: ");
scanf("%s",filename);
fptr=fopen(filename,"w");
if(fptr==NULL)
{
printf("Error occurred, try again.");
return 0;
}
fgets(string,"%s",fptr);
do
{
if(string[i]>='1' && string[i]<='9')
{
string[i]='$';
}
}
while(i!=100);
fclose(fptr);
}
There are basically two approaches at first glance, the first is to use fseek() and the second to read the file in its entirety and replace the characters to your criteria and finally write that in one shot. You can choose either of the approaches depending on your need. For large file you should prefer the former and for small file you can prefer the latter.
Here's an example code of the former:
#include <stdio.h>
int main() {
// Open the file
FILE *fptr = fopen("input.txt", "r+");
if (!fptr) {
printf("Error occurred, try again.");
return -1;
}
int c;
// Iterate through all characters in a file
while ((c = getc(fptr)) != EOF) {
// Check if this current character is a digit?
if (c >= '0' && c <= '9') {
// Go one character back
if (fseek(fptr, -1, SEEK_CUR) != 0) {
fprintf(stderr, "Error while going one char back\n");
return -1;
}
// Replace the character with a '$'
if (fputc('$', fptr) == EOF) {
fprintf(stderr, "Error while trying to replace\n");
return -1;
}
}
}
// Flush the changes to the disk
if (fflush(fptr) != 0) {
fprintf(stderr, "Error while flushing to disk\n");
return -1;
}
// Close the file
fclose(fptr);
return 0;
}

Resources