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)
Related
my C program does 3 things:
reads from a text file
converts all letters into upper-case
prints the converted text into the console.
Here are how many times I'm opening and closing those 2 files in my program:
Original => 1 for "r"
New => 2 first for "w+" and last for "r"
Is there a better way to write to a file and read from it without opening and closing a multiple times? (even though I only opened and closed twice, I wanna build a good practice)
#include <stdio.h>
#include <ctype.h>
int main()
{
const char ORIGINAL[] = "challenge2.txt";
FILE *fp = NULL;
FILE *fpNew = NULL;
char ch, ch2;
///////////// open the original txt file to read /////////////
fp = fopen(ORIGINAL, "r");
if (fp == NULL)
{
perror("Error opening the file");
return (-1);
}
///////////// create and write on a new file /////////////
fpNew = fopen("challenge2_copy.txt", "w+");
printf("\n============== Original text ==============\n");
while ((ch = fgetc(fp)) != EOF)
{
printf("%c", ch);
ch = toupper(ch);
fputc(ch, fpNew);
}
fclose(fp);
fp = NULL;
fclose(fpNew);
fpNew = NULL;
///////////// call the new file to print the converted text /////////////
fpNew = fopen("challenge2_copy.txt", "r");
if (fpNew == NULL)
{
perror("Error opening the file");
return (-1);
}
printf("\n============== Converted to Uppercase ==============\n");
while ((ch2 = fgetc(fpNew)) != EOF)
{
printf("%c", ch2);
}
fclose(fpNew);
fpNew = NULL;
return 0;
}
Here's the console output:
============== Original text ==============
hello I AM JACK
I AM TESTING lowerCASE
GONNA convert THIS into
UPPERcase
i hope THIS works
============== Converted to Uppercase ==============
HELLO I AM JACK
I AM TESTING LOWERCASE
GONNA CONVERT THIS INTO
UPPERCASE
I HOPE THIS WORKS
Good practices, performance, dangers.
MS Visual Studio suggest using fopen_s as good practise :)
Sometimes reopening file sometimes makes code more clear to read in big projects.
As for performance, it will take some time for processor to make new FILE instance and fill it with all file properties.
There can also be some interrupts eg. after releasing ownership for a while cloud sync. tools may want to back up newly created file and will block accessing it for other apps. (your program).
Performance solution.
So as to reuse a FILE instance you need only to jump into different place in FILE buffer (eg. start of the file).
You can achieve it with fsetpos or fseek functions from stdio.h.
https://www.cplusplus.com/reference/cstdio/fsetpos/
https://www.cplusplus.com/reference/cstdio/fseek/
Example FILE instance reusage.
/* fsetpos example */
#include <stdio.h>
int main ()
{
FILE * pFile; fpos_t position;
#define buffSize 1024 //1KB
char s[buffSize];
//Write
pFile = fopen ("myfile.txt","w+");
fgetpos (pFile, &position);
fputs ("That is a sample",pFile);
//Reuse for reading
fsetpos (pFile, &position);
puts (fgets(s,buffSize, pFile));
//Next reuse for reading
fsetpos (pFile, &position);
puts (fgets(s,buffSize, pFile));
fclose (pFile);
return 0;
}
The above code produces the following result:
That is a sample
That is a sample
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;
}
seems something is wrong. I've made a library project but some functions seem to be malfunctioning
for example : When i choose my member list (Shown below) it exists the code.
in c version.
void addmember()
{
system("cls");
// creating a FILE variable
FILE *fptr;
// creating a character variable
char ch;
// open the file in write mode
fptr = fopen("username.txt", "w");
// take user input
printf("Enter your name: ");
ch = getchar();
printf("Save any more?(Y / N):");
if(getch()=='n')
mainmenu();
else
system("cls");
addmember();
}
void memberlist(){
char ch;
FILE *fptr;
// open the file in read mode
fptr=fopen("username.txt", "r");
// display the content of the file
printf("\nFile content:\n");
while( (ch = getc(fptr)) != EOF ) {
printf("%c", ch);
}
printf("\nEnd of file\n");
// close file
fclose(fptr);
return 0;
}
In memberlist do you check if the fopen works well ? Probably fptr is NULL
Several remarks in addmember() :
addmember call itself at the end of its body, unconditionally, it is an infinite recursion
for each recursive call you fopen("username.txt", "w"); and that for nothing, but you never close the file
only one character is read for the name, it's suspicious
My assignment:
Write a program that asks the user whether to read or write a file. If writing a file, it then asks for a line of text, and writes it to a file. If reading, it reads the files and outputs it to the screen. The text is written out in non-binary mode - which is different than the file reading and writing for project #2. Remember how we used fgets() with string input. There is also an fputs().
I am trying to code the write section, but I cannot figure out what my mistake is. Also I do not really know how to create the read section. Do I only have to open the file then?
My code is:
#include <stdio.h>
#define HOLD_SCREEN while(getchar()!='q')
int write() {
int num;
FILE*fptr;
fptr = fopen_s;
if (fptr == NULL) {
printf("ERROR");
exit(1);
}
printf("Enter num: ");
scanf_s("%d", &num);
fprintf(fptr, "%d", num);
fclose(fptr);
return(0);
}
int main(void) {
while (1) {
printf("\n\tEnter an option: (R)ead or (W)rite a file or enter a q if you want to quit: ");
char buf[50];
buf[0] = '\0';
scanf_s("%s", buf, 50);
switch (toupper(buf[0])) {
case 'W':
write();
break;
case 'R':
printInventory();
break;
case 'Q':
return(0);
}
}
HOLD_SCREEN;
return(0);
}
I would really appreciate your help.
For writing:
fopen_s requires 3 parameters,
errno_t fopen_s(FILE** pFile, const char *filename, const char *mode);
an example being (in write mode)
errno_t err;
FILE *fptr
err = fopen_s(&fptr, "text.txt", "w" );
I am also taking some liberties and guessing this is the microsoft stack by the use of fopen_s instead of fopen. Otherwise, you should be using fopen like
FILE *fptr
fptr= fopen("text.txt", "w");
For reading:
Similar except the 3rd parameter would be err = fopen_s(&fptr, "text.txt", "r" ); or fptr = fopen("text.txt, "r") and use fgets to read a line of input (lots of examples out there).
I am implementing a storage manager to open, create, read and write a file using file pointers and file handler. But i am not able to write efficient code to implement all of my read functions of my storage manager. The read function of my storage manager has to implement the following:
To read first block of a file
To read current block of a file
To read previous block of a file
To read next block of a file
To read last block of a file
Any suggestions and code examples would be helpful to me.
The following is the code written by me to read a data file using file pointer -
*/
#include
#include
void main()
{
FILE *fptr;
char filename[15];
char ch;
printf("Enter the filename to be opened \n");
scanf("%s", filename);
/* open the file for reading */
fptr = fopen(filename, "r");
if (fptr == NULL)
{
printf("Cannot open file \n");
exit(0);
}
ch = fgetc(fptr);
while (ch != EOF)
{
printf ("%c", ch);
ch = fgetc(fptr);
}
fclose(fptr);
}