I can't copy the contents of one file to another in C because there is a segmentation fault occurring and I don't know the cause.
I know it has something to do with the syntax of fgets or the way I am giving the size of the buffer.
char* argument = argv[2];
char buffer[argc + 1];
FILE *fp;
FILE *quiz_log;
fp = fopen(argument, "r+");
quiz_log = fopen("quiz.log", "a");
fgets(buffer, 80, fp);
memcpy("quiz.log", buffer, 80);
fclose(quiz_log);
fclose(fp);
Expected: Successful write to file "quiz.log"
Actual: Segmentation Fault: 11
argc has nothing to do with the size of the file, it's the number of command line arguments. So there's no reason to use it as the size of the buffer.
Rather than try to read the file all at once, use a fixed-size buffer and read the file in a loop. Use fread() rather than fgets(), since that just reads one line.
You need to use fwrite() to write to the output file, not memcpy().
#define BUFFER_SIZE 1000
char* argument = argv[2];
char buffer[BUFFER_SIZE];
FILE *fp;
FILE *quiz_log;
fp = fopen(argument, "r");
if (fp == NULL) {
printf("Unable to open input file\n");
exit(1);
}
quiz_log = fopen("quiz.log", "a");
if (quiz_log == NULL) {
printf("Unable to open quiz.log\n");
exit(1);
}
size_t n;
while ((n = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) {
fwrite(buffer, 1, n, quiz_log);
}
fclose(quiz_log);
fclose(fp);
Related
Okay, so I have tried to read a whole file with fread(), and I can do it successfully, but the longer the file, the more the excess characters I get on the output.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
FILE* fpointer = fopen("test.txt", "r");
char* wholeFile;
long int fileSize;
if (fpointer == NULL) return 0;
fseek(fpointer, 0, SEEK_END);
fileSize = ftell(fpointer);
rewind(fpointer);
printf("fileSize == %ld\n", fileSize);
wholeFile = (char*)malloc(fileSize+1, sizeof(char));
if (wholeFile == NULL) return 1;
fread(wholeFile, sizeof(char), fileSize, fpointer);
fclose(fpointer);
wholeFile[fileSize] = '\0';
printf("This is whole file:\n\n%s", wholeFile);
free(wholeFile);
return 0;
}
If the file looks like this:
This is cool file.
I get this as output:
This is cool file.²²²²
And if the file is like this:
This
is
cool
file.
I get this as the output:
This
is
cool
file.═══²²²²
Any idea where I'm wrong?
EDIT: Edited code according to comments.
You need to allocate one more than the size of the file and set the last position in the buffer to 0.
C expects character arrays to be null terminated.
Use "rb" to open the file in binary mode. This will ensure you get a reliable count of bytes in the file from Windows.
FILE* fpointer = fopen("test.txt", "rb");
wholeFile = (char*)malloc(fileSize + 1);
wholeFile[fileSize] = '\0';
The goal of this program is recover JPGs from a file.
I've been working on this problem for about four or five days in the CS50 online class and I just cannot figure it out. I continue to get a segmentation fault and I have no idea why.
I've tried debug50 and find that I get the fault when the program tries to write to a new file. Why it does this I cannot figure out.
I've been bashing my head up against a wall on this one and I've completely erased and rewritten it multiple times. Any help would be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage ./recover file.type\n");
return 1;
}
char *infile = argv[1];
FILE *inptr = fopen(infile, "rb");
if (inptr == NULL)
{
fprintf(stderr, "Could not open file designated to be recovered\n");
fclose(inptr);
return 2;
}
int counter = 0;
FILE *img;
uint8_t buffer[512];
while (fread(buffer, sizeof(*buffer), 512, inptr))
{
if (buffer[0] == 0xff &&
buffer[1] == 0xd8 &&
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
{
if (counter > 0)
{
fclose(img);
}
char filename[8];
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
counter++;
}
if (counter !=0)
{
fwrite(buffer, sizeof(*buffer), 512, img);
}
}
fclose(img);
fclose(inptr);
return 0;
}
char filename[7];
sprintf(filename, "%03i.jpg", counter);
A seven character string takes up 8 chars due to the NUL-terminator \0. Make the array larger so you don't write past the end of it.
if(img == NULL)
{
fprintf(stderr, "Could not create image file\n");
fclose(img);
return 3;
}
If the img didn't open you don't need to close it. On the other hand, if it did open then you do need to close it. Move the fclose() call to the end of the loop.
In addition to the answer above,
Look at the syntax of the fwrite function:
https://en.cppreference.com/w/c/io/fwrite
size_t fwrite( const void *buffer, size_t size, size_t count,
FILE *stream );
According to the documentation, the size parameter is the size of each value in the buffer.
In your code, you have:
fwrite(buffer, 512, 1, img);
The problem is obvious.
It looks like you do the same for fread. The syntax of the function is:
https://en.cppreference.com/w/c/io/fread
size_t fread( void *buffer, size_t size, size_t count,
FILE *stream );
In your code you do:
fread(buffer, 512, 1, inptr)
But it should be
fread(buffer, sizeof *buffer, 512, inptr)
As an aside, when dealing with such files, I recommend opening them in binary mode so as to not tamper with the data being read.
FILE *inptr = fopen(infile, "rb");
Finally you should make use of the return value of fread which tells you the number of bytes that was actually read. You can then make use of this value in fwrite to make sure you write the correct number of bytes.
Okay, so I figured out that it was the NOT operator that I had put in the last if statement when what I should have put was:
if (counter != 0)
{
fwrite(buffer, sizeof(buffer), 1, img);
}
I am however still confused as to why the program returned a segmentation fault.
My understanding is that when the program reached this particular if statement it would not execute because the counter would be evaluated as false.
Wouldn't the program then just end after reading the whole input file returning 0?
Where does the segmentation fault come from?
In this code I opened my files in my open_file function. Then the process_file function needs to copy the text from my in file and Copy it to an out file. Right now it produces a new file but it is blank. It does not give me any error messages. I do not know what is wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 100
FILE* open_file(char prompt[], char mode[]);
FILE* process_file(FILE* in, FILE* out);
int main(int argc, const char * argv[]) {
FILE* in = NULL;
FILE* out = NULL;
printf("MAD-LIBS Text Processor\n");
printf("The Program will open a mad-libs file, ask you to fill various words, and produce a funny story.\n");
open_file("Enter mad-lib file name:\n", "r");
open_file("Enter file name for resulting story:\n", "w");
process_file(in, out);
fclose(in);
fclose(out);
return 0;
}
/* open_file = prompts user for file name & and attempts to open it, if it fails it prompts the user again. */
FILE* open_file(char prompt [], char mode[]) {
char filename[255];
FILE* in;
do {
printf("%s", prompt);
scanf("%s", filename);
in = fopen(filename, mode);
if (in == NULL) {
printf("Unable to open file: %s. Try Again!\n", filename);
}
} while(in == NULL);
return in;
}
/* process_file = processes entire input file and writes it to output file */
FILE* process_file(FILE* in, FILE* out) {
char content[MAX_LEN];
char NewContent[MAX_LEN];
//gets whats in file in
while(fgets(content, content[MAX_LEN], in) != NULL) {
fputs (content, stdout);
strcat(NewContent, content);
}
// copies it
while (fgets(content, content[MAX_LEN], in) != NULL) {
fprintf(out, "%s", content);
}
printf("Successfully copied file\n");
return in;
}
You never assign the FILE* from open_file function to your variable, so it never gets processed.
in = open_file("Enter mad-lib file name:\n", "r");
out = open_file("Enter file name for resulting story:\n", "w");
You are not storing the FILE pointers that open_file is returning, so in
and out remain uninitialized.
You have to do:
in = open_file("Enter mad-lib file name:\n", "r");
out = open_file("Enter file name for resulting story:\n", "w");
process_file(in, out);
Also your process_file is wrong. NewContent is not initialized, when you do
strcat(NewContent, content);
this yields undefined behaviour. Declare NewContent like this:
char NewContent[MAX_LEN] = { 0 };
so that it is properly \0-terminated.
Also depending on the size of the file you are copying, MAX_LEN might not be
long enough to hold the whole file. In that case you would overflow the buffer.
It would be better not to use NewContent in the first place and write to out
in the same reading loop:
FILE* process_file(FILE* in, FILE* out) {
char content[MAX_LEN];
//gets whats in file in
while(fgets(content, MAX_LEN, in) != NULL) { //<- your fgets was wrong
fputs (content, stdout);
fprintf(out, "%s", content); // or fputs(content, out);
}
printf("Successfully copied file\n");
return in;
}
And you were calling fgets incorrectly (look at my corrected code)
Also bear in mind, that you did have 2 loop doing while(fgets(...) != NULL.
Well, the first loop ends, that's because fgets returns NULL, most likely
because the whole file was read or there was an I/O error. In either case
subsequent calls of fgets will return NULL as well, so your second loop
would not even be executed at all.
I have these lines in my C program:
int main(int argc, char **argv) {
int i=0, p=0;
FILE* fp;
fp = fopen("jacina.txt", "w+");
fscanf (fp, "%d", &i);
if (ftruncate(fp, 0) == -1) {
perror("Could not truncate")
};
p = i+10;
fprintf(fp, "%d", p);
}
After building this code to OPKG in OpenWRT (from Ubuntu), how can I read and write to this textual file which is located on any disk location where is located this OPKG?
Your code doesn't make any sense. To write the input given by user to a file:
Create a file first. Take input from user (say any string) and write it to the file with the help of file descriptor (fp) and close the file so that all buffers get flushed.
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);
fprintf() too can be used instead to write data into a file.
Similarly to read from a file you can use fgets() or fread() to store the contents of the file in a buffer and display the contents of the file. Hope it helps.
I am try to write a buffer so I can remove a lot of null "00" characters in a file. The characters are useless and are completely random. They are wreaking havoc on the searcher in the program. The code below compiles but just seems to hang when a file is passed to it. Any suggestions will be helpful.
void ReadFile(char *name)
{
FILE *dbg;
char *buffer;
unsigned long fileLen;
//Open file
dbg = fopen(dbg, "w+");
if (!dbg)
{
fprintf(stderr, "Unable to open file %s", name);
return;
}
//Get file length
fseek(dbg, 0, SEEK_END);
fileLen = ftell(dbg);
fseek(dbg, 0, SEEK_SET);
//Allocate memory
buffer = (char *)malloc(fileLen+1);
if (!buffer)
{
fprintf(stderr, "Memory error!");
fclose(dbg);
return;
}
//Read file contents into buffer
fread(buffer, fileLen, 1, dbg);
for(i = fileLen-1; i >= 0 && buffer[i] == 0; i--);
i++;
if (i > 0)
{
fwrite(buffer, 1, i, dbg);
}
fclose(dbg);
//Do what ever with buffer
free(buffer);
}
Change
dbg = fopen(dbg, "w+");
to
dbg = fopen(name, "w+");
Also, if you want to read the file, change it then write it, you shouldn't open it with "w+". You should first open the file with "r", read from it, do whatever change you want, then fclose it, then again open it but this time with "w" so that you write over it. After you have opened it in "w"rite mode, you can write the modified buffer back into the file.
You opened a file for writing and then you try to read from it.
Check the return value of fread and all the other calls.