Why my code does not write the results to the file? - c

I am writing a code that reads the characters from a file, and then if one of these characters is 'A' it should be changed to 'Z', after these changes are made it should write it back to the file (not append, but write), but whenever I open the file after running the code or it is empty, corrupted, or the compiler shouts at me (since I tried correcting it by making some changes, here is the code I have so far:
int main(){
char variable1[2000000];
FILE *filePointer1;
FILE *filePointer2;
int counter;
int exact_char_numb;
filePointer1 = fopen("File.txt", "r");
filePointer2 = fopen("File.txt", "w");
fread(variable1,2000000,sizeof(char), filePointer1);
for(counter = 0; counter<= 2000000 ; counter ++){
if(variable1[counter] == 'A'){
variable1[counter] = 'Z';
}
if(variable1[counter] == '+'){
exact_char_numb = counter; // I am using '+' to mark the end of
} // the file (for now)
}
fwrite(variable1,sizeof(char),exact_char_numb,filePointer2);
printf("%s\n", variable1);
printf("%d\n", exact_char_numb);
return 0;
}

In this call:
fwrite(variable1,sizeof(char),exact_char_numb,filePointer2);
the variable exact_char_numb is likely equal to zero, so you don't get any output. You should turn on all warnings and the compiler will complain to you about the variables that can be used without initializing them first.

"but whenever I open the file after running the code or it is empty, corrupted, or the compiler shouts at me..."
You should check whether the opening of the streams to file.txt were successful by checking the returned pointers for a null pointer before doing any operations with the streams:
if (!(filePointer1 = fopen("File.txt", "r")))
{
fputs("Error occurred at opening file to read!", stderr);
exit(1);
}
if (!(filePointer2 = fopen("File.txt", "w")))
{
fputs("Error occurred at opening file to write!\n", stderr);
exit(1);
}
Furthermore, you donĀ“t need to do have two pointers to two different streams. Use r+ mode:
if (!(filePointer = fopen("File.txt", "r+")))
{
fputs("Error occurred at opening file!", stderr);
exit(1);
}

Related

Is fclose() necessary in read only file pointers?

I know it's good practice closing every file pointer that is opened, but I've been thinking that fclose() only actually does something when someone is working with files on write/all mode where the user actually needs to save the new content on the file.
But does having no fclose() actually affects read only pointers in any way? I've done some testing but I haven't gotten anything different from when I was using fclose().
Is there something else that I should be aware?
Opened file pointers may leak without fclose() and they may prevent from opening more files when you do file operations many times.
This is a test code that do fopen() many times.
#include <stdio.h>
int main(void) {
int i;
for (i = 0; i < 1000; i++) {
FILE* fp = fopen("test.txt", "r");
int data;
printf("%3d : ", i);
if (fp != NULL) {
if (fscanf(fp, "%d", &data) == 1) {
printf("data = %d\n", data);
} else {
puts("read failed");
}
fclose(fp);
} else {
puts("fopen failed");
}
}
return 0;
}
This code successfully done 1000 operations on Wandbox.
On the other hand, When I commented out the fclose(fp); line, the operation began to fail after successful 251 operations.
When working with files I open file with "w+" to create or overwrite existing file. And then when I want to write new entry to the file I open it again with "wa" write what you need using fprintf and then close it.

When my fprintf receives user input it crashes

This is a basic address book program that a user can add and delete people from and I am trying to eventually take the data saved in the array and store it in a text file.
In the choose function when ichoice == 8 the program is supposed to print the integer itter to the text file list.txt. It will print 0 when the program first opens and I haven't done anything to change it, but when I add names to the address book causing itter to increase the program crashes whenever I go back and try to save to list.txt.
else if (ichoice == 8) {
FILE *outFile = fopen("list.txt", "w");
if (outFile != NULL) {
printf("%d", itter);
fprintf(outFile, "%d", itter);
}
fclose(outFile);
}
There are some issues in the code fragment:
you fclose(outFile) even if the fopen call was unsuccessful.
you do not append a newline after the number, causing further output to be indistinguishable from the conversion of itter.
fopen("list.txt", "w"); will truncate the file if it already exists: this might not be the expected behavior.
Here is a modified snippet:
else if (ichoice == 8) {
FILE *outFile = fopen("list.txt", "w"); // or possibly "a"
if (outFile != NULL) {
printf("%d\n", itter);
fprintf(outFile, "%d\n", itter);
fclose(outFile);
}
}

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;
}

C - Why is fp == NULL true after fopen(filename, "r")?

I am trying to read the number of lines of a file in Ubuntu. For my code I'm using CodeBlocks.
This is the code I've made.
int countlines()
{
// count the number of lines in the file called filename
FILE *fp = fopen("words", "r");
int ch=0;
int lines=0;
if (fp == NULL){
return 0;
}
lines++;
while(!feof(fp))
{
ch = fgetc(fp);
if(ch == '\n')
{
lines++;
}
}
fclose(fp);
return lines;
}
If I call countlines(), the return value is a 0, that is because he checks if fp==NULL, and that is true.
I placed words in the same folder as my main. The executable file is in Projectfolder/bin/Debug.
Words looks like this:
"albatros",
"olifant",
"kantklos",
"robijn",
"internet"
The final goal is to fill an array with the words of the file words, without using #include "words".
Check what the working directory is set to. It might not be pjt/bin/Debug. Also, try specifying full path to the file.
if (fp == NULL){
return 0;
}
fp is checked with NULL, because, fopen returns pointer, if it succeed, it will be non-NULL, so if fp == NULL, then file open does not succeed. That's why program cannot proceed, and just return.
Hmmm!!! It could have been the fact that the file extension for "words" was not specified. Otherwise, I couldn't find anything else wrong with the program.

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