.txt file extension in terminal - c

How come when I type in "(filename).txt" as part of one of the argument in terminal my code doesn't run and gives me a segmentation fault (core dumped)? but if I type "(filename)" instead then the code runs perfectly?
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv){
FILE *inFile = fopen(argv[1], "r");
FILE *outFile = fopen(argv[2], "w+");
char ch = fgetc(inFile);
while(ch != EOF){
fputc(ch, outFile);
ch = fgetc(inFile);
}
}
I skipped error checking writing this small sample code of what I mean. Terminal input would be
"./(program name) (filename).txt (filename2).txt" but this produces a segmentation fault (core dumped)
Whereas, if I type this in
"./(program name) (filename) (filename2) without the .txt file extension the code runs

If you put a debug statement as the first thing in your program printing the contents of argv[1] and argv[2] then you will be able to see the problem and we won't have to guess exactly what you are trying to do. It is very hard for us to understand this issue with a MCVE because you are opening files that exist on your computer but which might not exist on ours. So it could crash on your machine, but have some different error on mine.
"I skipped error checking" ... well that's fine when things work, but here something is going wrong: why not check the return codes and print out the error if there is one. For example:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv){
FILE *inFile;
FILE *outFile;
if (argc < 3) {
fprintf("Only got %d arguments!\n", argc);
exit(1);
}
printf("arg1: %s, arg2: %s", argv[0], argv[1]);
inFile = fopen(argv[1], "r");
if (inFile == NULL) {
perror("Failed on in file: ");
exit(1);
}
outFile = fopen(argv[2], "w+");
if (outFile == NULL) {
perror("Failed on out file: ");
exit(1);
}
int ch = fgetc(inFile); /*as per comments this should be int */
while(ch != EOF){
fputc(ch, outFile);
ch = fgetc(inFile);
}
}

Nothing in your program should behave differently depending on the name of the input or output file.
But you don't check whether the fopen() calls succeeded.
I think what's happening is that the input file with the .txt extension simply doesn't exist. This causes fopen to fail, returning a null pointer, which you then assign to inFile. fgetc(inFile) then crashes.
Always check whether your calls succeeded or failed.
And as I mentioned in a comment, you need to assign the result of fgetc() to an int, not a char. It returns either a character value or the negative value EOF.
In addition you don't need two calls to fgetc, one before the loop and the other in the loop.
Suggested reading: section 12 of the comp.lang.c FAQ.

Related

Writing to a file in C segmentation Fault

I have a function that gets a string from the user and then does the following
void TraverseFile(char *inFile, char *outFile)
{
FILE *pIn;
FILE *pOut;
pIn = fopen(inFile, "r");
char c;
if (pIn == NULL)
{
printf("File not found");
}
pOut = fopen(outFile, "w");
if (pOut == NULL)
{
fclose(pIn);
printf("The write file cannot be opened.\n");
exit(1);
}
else{
while(1) //while it is not the end of input file
{
c= putchar(tolower(fgetc(pIn)));
if (feof(pIn)) break;
fputc(c,pOut);
}
fclose(pOut);
}
fclose(pIn);
}
Two things are happening: the while loop is giving me a segmentation fault. I think after input is because fgetc() returns in an int and I want to convert to a char. And the creation of the second file has a weird dot next to the txt name (see picture).
At least these problems
Missing .h
Add
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
Wrong type
fgetc() returns an int to handle the typical 257 different return values. #Avi Berger
// char c;
int c;
Using a char value that is negative and not EOF is undefined behavior with tolower(). By saving in int, c will have a value in the unsigned char range or EOF.
while(!feof(pIn)) wrong
Why is “while( !feof(file) )” always wrong?
int c;
while((c = fgetc(pIn)) != EOF) {
c = tolower(c);
fputc(c,pOut);
}
Error lacks exit
When pIn == NULL, no point in continuing. #Retired Ninja
if (pIn == NULL) {
printf("File not found");
exit(1); // Add
}
Without an early exit, fclose(pIn); is undefined behavior as pIn==NULL.
Bad file name
OP has "creation of the second file has a weird dot next to the txt name". Certainly due to improper filename formation like insufficient buffer size for the name.

How to fix the segmentation fault error 11 appearing after running my code?

I'm trying to solve this question regarding moving data from a file to another in C. Running the program gives a segmentation error 11. I've attached a picture of the question. Exercise 4
I believe there is a problem in opening the files, I entered inside the terminal the C code script name: code.c file1.txt file2.bin -b. The files are included in the path.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char** argv){
size_t k;
char read1[100] = {};
FILE* s;
FILE* d;
if (argc < 4) {
printf("NA");
exit(1);
}
if (strcmp(argv[4], "-b") == 0) {
printf("binary file output\n");
d = fopen(argv[3], "wb");
if (d == NULL) {
printf("cant open d");
exit(1);
}
} else {
if (strcmp(argv[4], "-t") == 0) {
printf("textual file output\n");
d = fopen(argv[3], "w");
} else {
printf("error");
exit(1);
}
}
s = fopen(argv[2], "r");
if (s == NULL) {
printf("cant open s");
exit(2);
}
k = fread(read1, sizeof(char),100, s);
while (k != 0) {
fwrite(read1, k,1, s);
k = fread(read1, sizeof(char),100, s);
}
fwrite(read1, k,1, s);
fclose(s);
fclose(d);
return 1;
}
I expect to move all the data from file 1 to file 2, and file2 output can be binary or textual depending on the user input stream. Ignored the 'hexadecimal' case.
You seem to want to write a program that takes the name of an input file, an output file and a flag (-b or -t), so I guess you're calling your program like this:
program infile outfile [-b|-t]
Those are 3 arguments. They will be argv[1], argv[2] and argv[3] respectively. You should not access argv[4]. Your program will segfault on strcmp(argv[4], "-b"). All your argv[x] should be shifted back by one. The check if (argc < 4) is ok though.
Another thing that can cause segmentation fault is reading from a FILE* that is not valid. You're not checking if d == NULL after the second fopen(). You should do that, and exit with an error in case it's NULL.
Other than this, other problems with your code are:
You should not call fwrite after exiting the while loop. You know that k == 0 when out of the loop. It is not harmful, but it's useless and will print nothing.
You should reorder the arguments of fwrite like this: fwrite(read1, 1, k, s).
Your last return 1 statement makes no sense, you should return 0, not 1, for sucessful program execution.
You don't need to initialize the array with char read1[100] = {}; since you don't use it before overwriting its content. Doing char read[100]; is just fine.
PS: you should learn to use GDB to debug your programs. Problems like this one are very easy to spot using GDB by just stepping through the instructions one by one.

How do I remove SEGFAULT here?

I created a function to print the contents of a file:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
where file is a global variable. GDB gives output as follows:
_IO_getc (fp=0x0) at getc.c:39
39 getc.c: No such file or directory.
(gdb) bt
#0 _IO_getc (fp=0x0) at getc.c:39
#1 0x000000000040075e in readFile ()
#2 0x00000000004006d4 in main ()
However, the file is present and I get the SEGFAULT after printing the contents of the file. It might be because the buffer here (c) is small but I am not sure. Also, I don't know how do I fix this even if that were the case. Can anyone suggest how do I proceed?
EDIT
I call the readFile function only once. Here is my calling function:
int main(int argc, char* argv[])
{
char * filename;
filename = argv[1];
readFile(filename);
printf("File Handler: %ld", (long)file);
fclose(file);
return 0;
}
You're passing in a filename that doesn't exist or for some other reason cannot be opened. Get rid of the segfault by checking for errors (you'll need to #include <errno.h> and <string.h> too for this:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
if (file == NULL) {
printf("Cannot open file '%s' : %s\n", filename, strerror(errno));
return;
}
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
Most likely your file is NULL and you are still trying to read it.
I simulated this behaviour (SEG fault) when I deleted this file.
If file exists then your code works fine.
Check what path you are passing.. If you are using single \ try with \\ and see if this works. First \ will work as escape sequence and final path will be send as D:\temp\use.dat to fopen.
readFile("D:\\temp\\user.dat");
Before you do anything with a file, you must ensure that you opened it successfully. This is done by checking that the file pointer received by calling fopen is not NULL.
Once you do this, you read using whatever function you choose until it returns a value that indicates failure to read — a NULL pointer for fgets, 0 or EOF for fscanf, or EOF for fgetc.
In any case, you challenge these return values in two ways. The first way is to check for read errors using ferror. The other way is to check whether the end of the file was reached using feof.
A complete program that should work, based upon your code:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
enum { OPEN_ERROR = 1, READ_ERROR };
enum { PARAM_EXIT = 1, OPEN_EXIT, READ_EXIT };
FILE *file = NULL;
int readFile(char* filename)
{
int c;
file = fopen(filename, "r");
if (file == NULL)
return OPEN_ERROR;
printf("The contents of file '%s' are:\n", filename);
while((c = fgetc(file)) != EOF)
printf("%c", c);
/*
* fgetc returns EOF on end of file and when an error occurs.
* feof is used to determine whether the end of the file was reached.
* Otherwise, we encountered a read error.
*/
if (feof(file))
c = 0;
else
c = READ_ERROR;
return c;
}
int main(int argc, char *argv[])
{
int status = 0;
if (argc == 1) {
fprintf(stderr, "usage: %s file\n", argv[0]);
return PARAM_ERROR;
}
/* Check that <program ""> wasn't used... */
if (argv[1][0] == '\0') {
fprintf(stderr, "error: empty filename detected, exiting. . .\n");
return PARAM_ERROR;
}
switch (readFile(argv[1])) {
case 0:
break;
case OPEN_ERROR:
fprintf(stderr, "error: file open failed - %s\n", strerror(errno));
status = OPEN_EXIT;
break;
case READ_ERROR:
fprintf(stderr, "error: file read failed - %s\n", strerror(errno));
status = READ_EXIT;
break;
default:
fprintf(stderr, "error: unknown error occurred, aborting...\n");
abort();
}
if (file != NULL)
fclose(file);
return status;
}
Of course, normally you would close the file in the same function in which it was opened (e.g. something like filep = openFile(...); readFile(filep); fclose(filep);, except error handling would be used of course).
I am completely changing my answer
Actually, the file that I was reading was open in gedit (which might explain why I was getting "NULL" even after printing the file contents. I closed the file and removed my NULL comparison code and it works perfectly fine.
Ok, from everybody's comments I got to know that you basically get a SEGFAULT when you read the contents of file that has NULL contents. I just made a simple fix in my while loop:
while((c != EOF))
{
printf("%c", c);
c = fgetc(file);
if(c == NULL)
break;
}
Problemo solved! (Although, the compiler gives me a warning of "comparison between pointer and integer".)

fclose causing exc_bad_access

I can't figure out why this fclose() in my c program is causing bad access. It was working fine and then I changed the if condition to only print when the strings do not equal eachother and suddenly it started causing problems. apart from the bad access error, it is also not printing anything to "newfile.txt"
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int main()
{
FILE * cFile;
FILE *outputfile;
FILE *newfile;
cFile = fopen("input.in", "r");
if (cFile == NULL){
printf("bad input file");
}
newfile = fopen("newfile.txt", "w+");
if (newfile == NULL){
printf("bad newfile");
}
char tempstring[15];
char tempstring2[15];
//get each line in the cFile
while (fscanf(cFile, "%15s", tempstring) != EOF) {
outputfile = fopen("outputlotnum.txt", "r"); //open/(or reopen) outputfile to check lines
if (outputfile == NULL){
printf("bad outputfile");
}
//get each line in the outputfile
while(fscanf(outputfile, "%15s", tempstring2) != EOF){
//if the line from cFile doesn't match the line from outputfile,
//then go ahead and print the line to the newfile.txt
if (strcmp(tempstring, tempstring2) != 0){
fprintf(newfile,"%15s \n", tempstring2);
}
//else don't print anything and continue on to the next line
}
fclose(outputfile); //close the outputfile after checking all the lines for a match
}
fclose(newfile); //throws bad access
fclose(cFile);
return 0;
}
Some reasons for library functions seg faulting include passing bad parameters into the function or that you have a memory scribbler. I suspect that in your case you have overflowed one or both temp string arrays on the stack and have corrupted the file handles. It's generally not a safe operation to fscanf/scanf into a buffer unless you can guarantee that the string you read will fit into that buffer.
To confirm this you could print out the file handles immediately after open, and again before close. They should be the same. If they are not then you have accidentally overwritten them.

fclose(in) segmentation faulting

I have reduced the program with comments, down to this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE * in;
in = fopen(argv[1], "r");
fclose(in);
fprintf(stderr, "clear **** \n");
return(0);
}
yet it still segfaults. Output is:
clear
Segmentation Fault
I know it's fclose(in) that's causing the problem, I just don't know why. For whatever reason, fclose(out) works perfectly fine.
First thing you should do is something like:
in = fopen(argv[1], "r");
if (in == NULL)
printf ("Could not open file '%s'\n" argv[1]);
else
fclose(in);
There's no guarantee in your original code that the fopen is actually working, in which case it will return NULL and the fclose will not be defined behaviour.

Resources