How to fix segmentation error in C programming? - c

I want to get the user input to open a txt file but I'm getting this compilation error called. [1] 85501 segmentation fault can someone help me with this? A sample input 2021-10-17
Here's git repo https://github.com/anjula-sack/diary
void DecryptEntry()
{
FILE *fptr;
char filename[20];
printf("Please enter the date of the entry you want to read, ex:2021-10-17\n");
fscanf(stdin, " ");
fgets(filename, 20, stdin);
strcpy(filename, ".txt");
printf("%s.txt", filename);
if ((fptr = fopen(filename, "r")) == NULL)
{
printf("Error! the entry doesn't exist");
}
}

Looking at the actual code from your github link, then you have this:
strcpy(filename, ".txt");
if ((fptr = fopen(filename, "r")) == NULL)
{
printf("Error! the entry doesn't exist");
}
fgets(message, 100, fptr);
First of all the strcpy is nonsense since it overwrites the filename and replaces it with ".txt". Since that is never a valid file name, fopen will always fail. And when it fails, you print an error message but continue execution, so the next fgets call will cause the crash.
Fix this by allocating enough space for filename, replace strcpy (overwrite) with strcat (append) and do a return etc upon failing to open the file.
You could easily have found these bugs yourself by single-stepping through the function using a debugger.

Related

Not able to open a file in read mode in c

char fileName[20];
puts("Enter the date.\n");
scanf("-> %s", fileName);
//Read the file
FILE *ptr;
ptr = fopen(fileName, "r");
if(ptr == NULL)
{
printf("\nNo file was found with this name\n");
exit(0);
}
else
{
printf("\nI FOUND the file.\n");
}
fclose(ptr);
I just want the user to enter a file name and then display 'found the file' as of now however even when the this code file and the text file are in same directory I am always getting the message'No file was found with this name' and I assure you that I am inputting the right file name(along with .txt extension).
Thank you #kaylum I got the answer.
The problem is with the scanf() statement. The scanf("-> %s", fileName) statement wants the user to input only -> otherwise it will fail.

File Pointer Not Being Assigned a Value When Using fopen()

I am trying to write a simple C program which will read data from a csv file and perform some calculations on this data.
Unfortunately I have a problem where a file pointer of mine, fptr , is not being assigned a value after calling fopen(). I know this is the case after stepping through VS 2017's debugger. Yet I do not know why this is the case. This is a huge problem and means my program will throw some very nasty exceptions any time I try to read data from the file or close the file.
My code is below:
main.c
#include<stdio.h>
#include <stdlib.h> // For exit() function
#include"constants.h" //For access to all project constants
/***************************************************************************************************************
To keep the terminal from automatically closing
Only useful for debugging/testing purposes
***************************************************************************************************************/
void preventTerminalClosure() {
//flushes the standard input
//(clears the input buffer)
while ((getchar()) != '\n');
printf("\n\nPress the ENTER key to close the terminal...\n");
getchar();
}
/***************************************************************************************************************
Read the given input file
***************************************************************************************************************/
void readInputFile(char fileName[]) {
FILE *fptr;
char output[255];
//open the file
if (fptr = fopen(fileName, "r") != NULL) { //read file if file exists
//fscanf(fptr, "%[^\n]", output);
//printf("Data from the file:\n%s", output);
printf("<--Here-->");
}else {
printf("\nERROR 1: File %s not found\n", fileName);
preventTerminalClosure();
exit(1);
}
fclose(fptr); //close the file
}
/***************************************************************************************************************
* * * Main * * *
***************************************************************************************************************/
void main() {
char testName[MAX_NAME_SIZE];
printf("Hello World!\n");
printf("Please enter your name: ");
scanf("%s", testName);
printf("It's nice to meet you %s!", testName);
readInputFile("dummy.txt");
preventTerminalClosure(); //Debug only
}
I have made sure that my fake file does indeed exist and is located in the correct location. Otherwise my code would hit the else block inside of readInputFile(). That is something I have thoroughly tested.
There is clearly something basic that I am missing which explains this pointer behavior; but what that is, I am not sure. Any help would be appreciated! :)
Use parenthesis to enforce order, so that fptr is compared against NULL after it has been assigned value returned by fopen:
FILE *fptr;
char output[255];
//open the file
if ( (fptr = fopen(fileName, "r")) != NULL)

fprint doesn't work in loop

I am trying to repeatedly read a string from the command line and print it to a file. This is my code:
int main ()
{
FILE* fp=fopen("test.txt","w");
char* tofile[10];
while(1){
printf("cat: ");
scanf("%s",tofile);
fprintf(fp,"%s\n",tofile);
}
return 0;
}
It works just fine outside the loop. But inside, it just doesn't print.
The fprintf function returns the correct amount of characters it has to print.
Note: I know there's a similar question out there, but it hasn't been answered yet, and I hope my code can help in this matter since it's simpler.
Well first it doesn't seem that what you want is reading on the command line.
The command line what you write right when you execute your program such as:
./main things that are on the command line
What it seems you want to do is to read on the standard input.
What you should consider is to use the fgets function, as it has a limit of characters to be read, so that you can store them "safely" into a buffer, like your tofile.
As you want to read on the standard input you can use the stdin stream (which is a FILE* that is automatically created for every program)
The line goes
fgets(tofile, 10, stdin);
Your loop becoming :
while (fgets(tofile, 10, stdin) != NULL) {
printf("cat: ");
fprintf(fp, "%s\n", tofile);
}
meaning: as long as we can read on the standard input, print "cat :" and store what we just read in the file controlled by the stream pointer fp.
Some important stuff
When you try to open a stream it may fail and you should test it:
char filename[] = "test.txt";
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
fprintf(stderr, "Failed to open the file of name : %s", filename);
return EXIT_FAILURE;
}
Right before exiting your main, you should also close the file and check if it has succeeded, like that for example:
if (fclose(fp) != 0) {
fprintf(stderr, "Failed to close the file of name : %s", filename);
return EXIT_FAILURE;
}
The whole thing becomes:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char filename[] = "test.txt";
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
fprintf(stderr, "Failed to open the file of name : %s", filename);
return EXIT_FAILURE;
}
char tofile[10];
printf("cat: ");
while (fgets(tofile, 10, stdin) != NULL) {
printf("cat: ");
fprintf(fp, "%s\n", tofile);
}
if (fclose(fp) != 0) {
fprintf(stderr, "Failed to close the file of name : %s", filename);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Improvements
I don't know if it is just a little program or it aspires to become a greater program.
In the last case you should consider using defines and not a magical number such as
#define BUFFER_MAX_SIZE 10
char tofile[BUFFER_MAX_SIZE];
while (fgets(tofile, BUFFER_MAX_SIZE, stdin) != NULL) { ... }
This helps for readability and makes the program less apt to debug when modifying such a size. Because with the define all the part of the code needing the size will still be fully functional without modifying them.
Please also keep in mind that your tofile acts as a buffer, and it's really a small buffer that can easily be overflowed.
This will work. fgets() returns the string it reads from the specified file pointer. If this string returns only a newline ("\n"), that means nothing was entered at stdin.
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *fp = fopen("test.txt","w");
// always check if fopen() == null
if (!fp) {
fprintf(stderr, "Could not write to file\n");
return 1;
}
char tofile[30];
printf("cat: ");
while (fgets(tofile, 30, stdin)) {
if (strcmp(tofile, "\n") == 0)
break;
fprintf(fp, "%s", tofile);
printf("cat: ");
}
// always fclose()
fclose(fp);
return 0;
}
Edited code.

C Program - File-io user input

I am trying to get a user to enter a specific file name and have the program be able to read it.
FILE *fp;
char file[10];
fgets(file, sizeof(file), stdin);
fp = fopen(file, "r");
if (fp == NULL) {
printf("File doesn't open\n");
return 1;
}
This is a section of my code and what i'm currently trying to do. When i run the program and enter the file name, the output is "File doesn't open" which is my error message.
The problem is that fgets also incorporates the newline character '\n' in the string read. You need to remove it,
char* p;
if(p = *strchr( file, '\n' ))
*p = '\0';
otherwise fopen will fail.
Assuming you meant fopen(file,...), before you can do that you must strip file of a newline. See man pages for fgets and [I suggest] strchr.
Use perror to print system error diagnostics:
int main(){
FILE *fp;
char file[10];
fgets(file, sizeof(file), stdin);
fp = fopen(file, "r");
if (!fp) {
perror(file);
return 1;
}
}
If you ask for file f, it'll print:
f
: No such file or directory
which should point you at the source of the problem (the fopen call may also fail for permissions reasons, for example).

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.

Resources