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

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.

Related

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

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

C Programming - Copy File Buffer and Write to File

I'm making some small changes to a preexisting application. The app is writing lines of text to a buffer and then flushing the buffer. I'm not sure when it actually writes the text to the file, but I'm trying to copy everything in that buffer and write a copy of it all out to a completely different file.
Below is the last line of writing to the preexisting buffer before it eventually calls fflush().
fprintf(_log, "-- FINAL TEXT LINE --\n");
Below is my code that I'm using in an attempt to copy that buffer to a separate file which is dynamically named according to the log time. This custom-%ld.log does not already exist and needs to be created.
char tmp[sizeof(_log)];
sprintf(tmp, "custom-%ld.log", (long int)lf->time);
FILE *fp1, *fp2;
char a;
fp1 = _log;
fp2 = fopen(tmp, "a");
if (fp2 != NULL) {
do {
a = fgetc(fp1);
fputc(a, fp2);
} while (a != EOF);
fflush(fp1);
fclose(fp2);
}
fflush(_log);
I'm sure my mistakes are very basic, but I don't know what I'm doing. I've tried dozens of suggestions on other websites, and suggestions here from other questions, but I'm not having any luck.
Yes, there are a few mistakes in here.
This will allocate a buffer of 4 or 8 bytes depending on the word size of your computer. 'sizeof' is a compile time directive that gives you the size of the underlying type.
char tmp[sizeof(_log)];
So do this instead (where 100 is just a big enough number to hold the result):
char tmp[100];
Next using a char for 'a' will not be able to hold the EOF value. Use int.
int a;
By fixing the definition of 'a' your loop is now not infinite, but it will eventually write the constant EOF to the file, which will be some garbled character. Change it like so:
while ((a = fgetc(fp1)) != EOF) {
fputc(a, fp2);
}
So in the end you should have:
char tmp[100];
sprintf(tmp, "custom-%ld.log", (long int)lf->time);
FILE *fp1, *fp2;
int a;
fp1 = _log;
fp2 = fopen(tmp, "a");
if (fp2 != NULL) {
while ((a = fgetc(fp1)) != EOF) {
fputc(a, fp2);
}
fflush(fp1);
fclose(fp2);
}
fflush(_log);
You are writing EOF to file before checking it with
do {
a = fgetc(fp1);
fputc(a, fp2);
} while (a != EOF);
You could try
int a; // make sure you have the correct type
while((a = fgetc(fp1)) != EOF)
fputc(a, fp2);
}
EOF is not (except some legacy formats) part of the file. It is an indicator returned by file reading functions.
Note that fflush(fp1); is undefined behaviour when fp1 is opened for input.
You say "custom-%ld.log" does not already exist yet you open it with
fp2 = fopen(tmp, "a");
Which would append, if you forgot to delete a previous version. To make sure it is a new file, open with
fp2 = fopen(tmp, "w");

Concatenate two .y inputs

I am having two inputs :video1.y and video2.y .I want to Concatenate these two files to create one video.y file ??I am writing code in C .It may be basic question but not able to do that !! Both inputs are having same hight and width .
Code:
int main()
{
// Open two files to be merged
FILE *fp1 = fopen("D:\\dump\\video1.y", "rb");
FILE *fp2 = fopen("D:\\dump\\video2.y", "rb");
// Open file to store the result
FILE *fp3 = fopen("D:\\dump\\video.y", "wb");
char c; //Change char to int as per answer given by user3710044..
//...Which is working !!
if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
{
puts("Could not open files");
exit(0);
}
// Copy contents of first file to video3.y
while ((c = fgetc(fp1)) != EOF)
fputc(c, fp3);
// Copy contents of second file to video3.y
while ((c = fgetc(fp2)) != EOF)
fputc(c, fp3);
printf("Merged video1.y and video2.y into video.y");
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}
video1.y and video2.y are of 55 MB .and my output is 3 KB.I am not able to concatenate this two inputs
The type of the c variable is a char this cannot hold the value for EOF and all 256 byte values.
As it happens on your machine char is a signed type so the cast return result from fgetc and the cast value of EOF actually mean that an EOF is found at the end of a file. The problem is that if the file contains an 0xFF byte this is also seen as an EOF.
In summary, change the type of c to an int.

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.

File handling program not working as expected in C

FILE *mails;
FILE *tempmails;
mails = fopen("mailer.txt", "r");
tempmails = fopen ("tempmailer.txt" , "a+");
char line[200],templine[200];
char blnklne[]="\n";
while(fgets(line, sizeof line, mails) != NULL)
{
int flag=0;
while(fgets(templine, sizeof line, tempmails) != NULL)
{
if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
{
flag = 1;
}
}
if(flag == 0)
{
fputs(line, tempmails);
}
}
fclose(mails);
fclose(tempmails);
tempmails = fopen ("tempmailer.txt", "r");
remove("mailer.txt");
FILE *newmails;
newmails = fopen("mailer.txt", "a");
while(fgets(templine, sizeof line, tempmails) != NULL)
{
fputs(templine, newmails);
}
fclose(newmails);
fclose(tempmails);
remove("tempmailer.txt");
I have written the above C code for the following purposes:
Have to read each line from mailer.txt and check if a line is blank or repeated and if both conditions are false have to enter it to a temp file tempmailer.txt
Remove the file mailer.txt and then create a new one and copy enter it into the new file one by one and then remove tempmailer.txt.
But on running what actually happens is:
Copies from mailer.txt to tempmailer.txt ALL the lines irrespective of any conditions given(undesired)
Deletes mailer.txt and creates a new mailer.txt(desired)
Copies from tempmailer.txt to the new file as such(desired)
Deletes tempmailer.txt(desired)
Whatever I do, I can't erradicate this problem. The OS is linux. Please help me. Thanks in advance.
Reset tempmails to the beginning of the file before starting each 2nd loop.
while(fgets(line, sizeof line, mails) != NULL)
{
int flag=0;
rewind(tempmails); /* go back to the begining */
while(fgets(templine, sizeof line, tempmails) != NULL)
{
/* ... */
}
}
You need to seek to the beginning of the file before the second while loop.
As it stands, your second while loop will never find any matching lines because it will always be pointed to the end of the file.
The repeat-detection code is very strange, it's reading from both files at the same time. You can't read from a file opened for append. Try mode a+.
This is solvable with a trivial shell script, do you really have to write it in C?
Maybe this part of code is the reason why you got your question 1
while(fgets(line, sizeof line, mails) != NULL)
{
int flag=0;
while(fgets(templine, sizeof line, tempmails) != NULL)
{
if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
{
flag = 1; /* this part may be not correct */
}
}
if(flag == 0)
{
fputs(line, tempmails);
}
}
If the program finds a line that makes if condition true, then the flag is set to 1, but next line maybe not make if condition true, and you program can not set the flag to 0.So you will never put the mismatch lines which are after the the matched line into the tempmails.
Disclaimer: This is not really an answer, but can definitely aid in debugging!
After the following lines, you should check if the pointers are NULL or not:
mails = fopen("mailer.txt", "r");
tempmails = fopen ("tempmailer.txt" , "a+");
if (mails == NULL) printf("Error: could not open file");
if (tempmails == NULL) printf("Error: could not open file");
Now you can at least know if it can open and read the files. To check whether fgets works, and isn't giving you errors, use ferror or feof.
You should add the same NULL checks for every time you call fopen on a FILE handle.

Resources