C read/write to file - Access Violation - c

I am trying to read and write simple Infix and Postfix expressions to a from a file. When the program reaches the lines where fgets is called, an Access Violation error pops up.
Code:
#include <stdio.h>
#include <stdlib.h>
#include "header3.h"
char inFx[100], postFx[100];
int main() {
FILE *fp = fopen_s(&fp, "input.txt", "r");
remove("output.txt");
FILE *fp2 = fopen_s(&fp2, "output.txt", "a");
if (fp == 0)
{
printf("Could not open file\n");
}
else
{
int i = 0;
while (fgets(inFx, sizeof(inFx), fp)) { //access violation during runtime here
size_t ln = strlen(inFx);
int n = expEvaluate(inFx, ln, postFx); //refers to other class
if (inFx[ln] == '\n')
inFx[ln] = '\0';
if (fp2 == 0)
{
printf("Could not open file\n");
}
else
{
while (*(postFx + i) != 0)
{
fputc(*(postFx + i++), fp2);
}
fputc('\n', fp2);
}
}
}
fclose(fp2);
fclose(fp);
return 0;
}

fopen_s() returns an error code, NOT the file handle (that is assigned to the first parameter).

You should not get the result of fopen_s into your FILE pointers.
Also, you should put your test on fp2 before your loop. If you cannot open the File, then you will read your whole file fp but you won't do anything.

Related

Running is fine but rename() does not work

Simple function code to delete a line from a text file by making a temporary text file that will store the new content once the line has been deleted and replacing the old Storage.txt file with the temporary file.
The delete() function works but my only problem seems to be the rename() function that seemingly won't do as intended.
THE CODE
void delete() {
struct task task;
FILE *fp;
char str[100];
char ch;
int delete_line = 0;
fp = fopen("Storage.txt", "r");
if (fp == NULL) {
printf("Error opening file");
fopen("Storage.txt", "w");
exit (1);
}
printf("\n\n\nAll Tasks\n");
printf("----------\n\n");
do {
ch = fgetc(fp);
printf("%c", ch);
} while (ch != EOF);
fclose(fp);
int line_no,ret;
char filename[] = "Storage.txt";
char newname[] = "temp.txt";
FILE *file, *temp;
file = fopen("Storage.txt", "r");
temp = fopen("temp.txt", "w");
printf("Select Line to delete: ");
scanf("d", &delete_line);
getchar();
temp = fopen("temp.txt", "w");
while (fgets(str, 99, fp) != NULL) {
line_no++;
if (line_no != delete_line) {
fputs(str, temp);
}
}
fclose(file);
fclose(temp);
remove(filename);
ret = rename(newname, filename);
if (ret == 0) {
printf("File renamed successfully");
} else {
printf("Error: unable to rename the file");
}
}
There are some problems in the code:
ch must be defined with type int to detect EOF reliably.
the do/while loop to read the file contents outputs the EOF indicator before testing it. You should use while ((ch = fgetc(fp)) != EOF) putchar(ch);
the identifier delete should be avoided to avoid confusing C++ programmers, use delete_line instead.
you should test for failure of fopen and remove and display the cause of the error.
if opening the file for reading fails, why do you create the file with fopen("Storage.txt", "w") ?
file temp.txt is open twice, which may prevent the rename operation on legacy systems.
line_no is not initialized. It should be initialized to 1 if lines are numbered starting at 1.
reading lines into an array is not reliable for this task as lines longer than 99 bytes will be counted more than once.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void delete_line() {
const char *filename = "Storage.txt";
const char *tempname = "temp.txt";
int ch;
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n", filename, strerror(errno));
exit(1);
}
printf("\n\n\nAll Tasks\n");
printf("----------\n\n");
while ((ch = getc(fp)) != EOF) {
putchar(ch);
}
fclose(fp);
int delete_line = 0;
printf("Select Line to delete: ");
if (scanf("d", &delete_line) != 1) {
fprintf(stderr, "invalid or missing input\n");
exit(1);
}
// read and discard the rest of the user input line
while ((ch = getchar()) != EOF && c != '\n')
continue;
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n", filename, strerror(errno));
exit(1);
}
FILE *temp = fopen(tempname, "w");
if (temp == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n", tempname, strerror(errno));
fclose(file);
exit(1);
}
int line_no = 1;
while ((ch = getc(file)) != EOF) {
if (line_no != delete_line)
putc(ch, temp);
if (ch == '\n')
line_no++;
}
fclose(file);
fclose(temp);
if (remove(filename)) {
fprintf(stderr, "Cannot remove %s: %s\n", filename, strerror(errno));
} else {
if (rename(tempname, filename)) {
fprintf(stderr, "Cannot rename %s as %s: %s\n",
tempname, filename, strerror(errno));
}
}
}
Your code opens the "temp.txt" file twice:
temp = fopen("temp.txt", "w");
...
temp = fopen("temp.txt", "w");
And closes it once. That will leave one open file descriptor to the file, untill the program exits.
remove() uses unlink() for deleting files. The man page of unlink() says:
If the name was the last link to a file but any processes still have
the file open the file will remain in existence until the last file
descriptor referring to it is closed.
Ensure that all file descriptors are closed when not needed anymore.
The rename may fail, if file of oldpath or newpath is still open.
temp = fopen("temp.txt", "w"); Call it twice
The two main bugs here are:
1.
scanf("d", ...) instead of
scanf("%d", ...)
scanf() needs a format string to know how to parse the input, just like printf() (the f is for format) needs it to know how to construct the output; and their format string syntax is almost the same.
2.
Unintialized line_no, meaning that it's not guaranteed to start at 0/1, thus it might not ever be equal to delete_line, and will not delete the line.

Error Segmentation Fault Core Dumped in C - Ubuntu

I am facing this error. I have searched on Internet and that solution is passing two arguments in main, argc and argv. I dont know why to use it and how i use it?
My program is to read a file that contains integers and print them
#include<stdio.h>
int main()
{
int no;
char ch;
FILE *ftr;
ftr = fopen("numbers.txt", "r");
while ((ch = fgetc(ftr)) != EOF)
{
no = ch - '0';
printf("%d", no);
}
fclose(ftr);
return 0;
}
The only explanation for this is that ftr == NULL, try
#include <stdio.h>
int main(void)
{
FILE *file;
char chr;
file = fopen("numbers.txt", "r");
if (file == NULL) {
fprintf(stderr, "cannot open the file\n");
return -1;
}
while ((chr = fgetc(file)) != EOF) {
fprintf(stdout, "%d", chr - '0');
}
fclose(file);
return 0;
}
Ideally you should check file opening and close by using the same level of checking as employed by these two snippets.
f = fopen(filename,"r");
if (f == NULL) {
fprntf(stderr, "fopen failed: %s", strerror(errno));
// and terminate the file IO here
}
..
..
if (fclose(f) == EOF) {
fprint(stderr, "fclose failed");
}

print 5 lines from input file

currently, I am writing code in c program for printing small portion of contents from the input file. Actually, in my code I can able to print just one single line. but, i have to print next 5 lines after that one line.
I am new to programming, please help to solve this problem**
code is given below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int lineNumber = 2;
int main()
{
FILE *file;
char line[100];
int count = 0;
///Open LS-dyna file to read
file = fopen("P:\\tut_c\\read\\df-read\\in.txt", "r");
if (file == NULL)
{
perror("fopen");
exit(EXIT_FAILURE);
}
else if ( file != NULL )
{
char line[256];
while (fgets(line, sizeof line, file) != NULL)
{
if (count == lineNumber)
{
printf("\n str %s ", line);
fclose(file);
return 0;
}
else
{
count++;
}
}
fclose(file);
}
return 0;
}
The first logical error occurs in your while loop, first iteration, when you close the file and return 0.
Next, there is no reason to have a counter for your lines, since there are many c functions that can handle finding the end of file (eof).
Instead:
Use a while loop for iteration through the file.
Use a standard library c function for file reading.
Check if file has reached the end.
If the line is still valid, then print the line.
Here is some code to reiterate:
int main()
{
FILE *file;
file = fopen("file.txt", "r");
if (!file){ // check if file exists
perror("fopen");
exit(EXIT_FAILURE);
}
else { // if file exists, then...
char line[256];
while(fgets(line, sizeof line, file)){
printf("\n str %s ", line);
}
fclose(file);
}
return 0;
}// end main

Unable to jump from one place another properly in excel file using C

I am writing a code in C to write data in .csv file. In this code I am just writing A in first column for five time then trying to write B from beginning of next column. Here is my code:-
#include "stdafx.h"
#include<stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
FILE *fp;
fp = fopen("Filename.csv", "w");
if(fp == NULL)
{
printf("Couldn't open file\n");
return 0;
}
for (int j = 0; j<5; j++)
{
fprintf(fp, "A\n");
}
for (int j = 0; j<5; j++)
{
fprintf(fp, ",B\n");
}
return 0;
}
My output expectation is like this:-
A B
A B
A B
A B
A B
But I am getting output like this:-
A
A
A
A
A
B
B
B
B
B
My idea is to learn to jump any column-row to any column-row is .csv file.
So, please help me to learn how to jump anywhere in the file.
You can parse line and join parsed part and a new part and write to file again. I think its not the best way but it works.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *fp, *fp2;
size_t len = 0;
ssize_t read;
char * line = NULL;
/* Write first part "A" */
fp = fopen("Filename.csv", "w");
if(fp == NULL)
{
printf("Couldn't open file\n");
return 0;
}
/* Write and done */
for (int j = 0; j<5; j++) fprintf(fp, "A\n");
fclose(fp);
/* Open templorary file */
fp = fopen("file.tmp", "a");
if (fp != NULL)
{
/* Open exiting file */
fp2 = fopen("Filename.csv", "r");
if(fp2 != NULL)
{
/* Read from exing file */
while ((read = getline(&line, &len, fp2)) != -1)
{
/* Remove new line character */
sscanf(line, "%512[^\n]\n", line);
/* Join and write to file */
sprintf(line, "%s B", line);
fprintf(fp, "%s\n", line);
}
/* Clean up memory */
fclose(fp2);
if (line) free(line);
}
/* End up */
fclose(fp);
remove("Filename.csv");
rename("file.tmp", "Filename.csv");
}
return 0;
}

Adding a file close statement causes a seg fault

When trying to close the file after reading it, I get a seg fault on running the program.
int inputDirectory()
{
char fileName[64];char directoryBuffer[256];FILE *fp;
printf("\n> Please type the filename containing the list of directories. >");
inputFix(fileName, sizeof(fileName));
fp = fopen(fileName,"r");
if(access(fileName, F_OK) == 0)
{
if (fp == 0)
{
printf("> Error opening file.");
return 1;
}
else
{
if (access(fileName, R_OK) == 0)
{
while (fgets(directoryBuffer, sizeof(directoryBuffer), (FILE*)fp))
{
readCheck(directoryBuffer);
printf("%s \n", directoryBuffer);
getInode(directoryBuffer);
}
}
else
{
printf("\n> File can't be read.");
}
}
}
else
{
printf("\n> File %s does not exist ", fileName);
}
fclose(fp);
return 0;
}
void inputFix(char string[],int length)
{
int ch, len = 0;
fgets(string, length, stdin);
string[strcspn(string, "\r\n")] = '\0';
len = strlen(string);
if (len == length - 1)
{
while((ch = getchar()) != '\n' && ch != EOF);
}
}
void readCheck(char string[])
{
string[strcspn(string, "\r\n")] = '\0';
}
Ive been reading into race conditions, but from my understanding there isn't one? Is there a need to check to see if the file exists before trying to open it? Is there a need to include some of the checks that I'm using?
Looking at these lines.
if (fp == 0)
{
printf("> Error opening file.");
fclose(fp); // NOT NEEDED. REMOVE THE LINE
}
It seems you don't need to call fclose when you were not able to open the file.
Remove the line.
If fp is null (equal to 0), you do not need to close it, the file was never opened to begin with. You should close fp after you are done successfully reading from it.
You are closing the file at the end regardless of whether the file ever opened or not. Calling fclose on an unopened file can cause a crash. Try this instead. I have moved the fclose statement to be called only when fp is not NULL.
int inputDirectory()
{
char fileName[64];char directoryBuffer[256];FILE *fp;
printf("\n> Please type the filename containing the list of directories. >");
inputFix(fileName, sizeof(fileName));
if(access(fileName, F_OK) == 0)
{
fp = fopen(fileName,"r");
if (fp == NULL)
{
printf("> Error opening file.");
return 1;
}
else
{
if (access(fileName, R_OK) == 0)
{
while (fgets(directoryBuffer, sizeof(directoryBuffer), (FILE*)fp))
{
readCheck(directoryBuffer);
printf("%s \n", directoryBuffer);
getInode(directoryBuffer);
}
}
else
{
printf("\n> File can't be read.");
}
fclose(fp);
}
}
else
{
printf("\n> File %s does not exist ", fileName);
}
return 0;
}
Only call fclose() on a FILE* which had been returned by a successful call to fopen().
To test wether fopen() had been successful compare its result against NULL. If this test succeeds the call had not been successful:
#include <stdio.h>
int main(void)
{
char filename[] = "myfile";
FILE * fp = fopen(filename, "r");
if (NULL == fp)
{
fprintf(stderr, "fopen(\"%s\", ...) failed.\n", filename);
}
else
{
fprintf(stderr, "fopen(\"%s\", ...) succeeded.\n", filename);
/* Perform operation on fp here. */
fclose(fp);
}
return 0;
}

Resources