check if function was called before - c

Here is my basic code that I'm trying to work with.
void test(){
FILE *input;
input = fopen("input.txt.", "r");
}
So I'm trying to check if file was already opened before, meaning that void test() function was called once before. I realy have no idea how to do that, i tried it with while and if.
Like this.
void test(){
FILE *input;
int open = 0;
while (open == 0){
input = fopen("input.txt", "r");
if (input == NULL){
printf("File wasnt opened.\n");
}
if (input != NULL){
printf("File is opened.\n");
}
open = open + 1;
}
if(open!=0){
printf("file is already opened.\n");
}
}

Use a local static variable.
void test (void)
{
static bool called_before = false;
if(called_before)
{
do_this();
}
else
{
do_that();
called_before = true;
}
}

Supposing that your intent is for test to open the file just once but to read from the file each time it is called, you can make input static:
void test(void)
{
/* Since input is static, it will be initialized with NULL when the
program starts and we will retain its value between calls to
the function.
*/
static FILE *input = NULL;
// If input has not been set for an open file yet, try to open it.
if (!input)
{
input = fopen("input.txt", "r");
if (!input)
{
fprintf(stderr, "Error, unable to open input.txt.\n");
exit(EXIT_FAILURE);
}
}
for (int c = fgetc(input); c != EOF && c != '\n'; c = fgetc(input))
putchar(c);
putchar('\n');
}
Note static objects should generally be avoided, as they complicate program state and so may lead to more bugs. It is okay to play with them in student programs to learn how they work, but their use in real-world applications should be limited.

Related

fopen() function does not work as expected on my friends PC

I have written the following file:
#include <stdio.h>
#include "config.h"
FILE* fptr;
void writeConfig(const char* new_api_key) {
if ((fptr = fopen("../config.txt", "w")) == NULL) {
printf("Error creating config file");
} else {
fprintf(fptr, "%s", new_api_key);
fclose(fptr);
}
}
char* readConfig(char* buffer, size_t bufSize) {
if ((fptr = fopen("../config.txt", "r")) == NULL) {
return "error opening config file";
} else {
if ((fgets(buffer, bufSize, fptr)) == NULL) {
fclose(fptr);
return "error reading config file";
}
else {
fclose(fptr);
return buffer;
}
}
}
And on 3 different tested machines this code works. But on one of my friends PC it does not.
The code gets executed as following:
char buffer[50];
long long bufSize = 50;
char* message = "example123";
writeConfig(message);
printf(readConfig(buffer, bufSize));
As seen in the "writeConfig" function, this creates a new txt file named "config.txt" and then tries to read it via the "readConfig" function. Weird is, that the "writeConfig" function does not throw an error, even tho the file is not created in his case. Only the "readConfig" function throws the error "error opening config file" which means that fopen() returned NULL.
We have also tried manually creating the config.txt file but the code still failed at the "readConfig" function with the same error.
I have the feeling that it could be about some read and write permissions? But i can not come up with a solution.
(Both PC run Windows)
Any help is appreciated :)

read a text file, make some trivial transformation character by character (swapping the case of all letters), write result to text file

I have to read a text file, make some trivial transformation character by character (swapping the case of all letters), write results to the text files. I wrote this code, but it's not working. Please guide me in this regard. Thanks for in Advance
#include <stdio.h>
#include <stdlib.h>
int main() {
char c[1000];
char x[100];
char var;
int i;
FILE *fptr;
if ((fptr = fopen("text.txt", "r")) == NULL) {
printf("Error! opening file");
// Program exits if file pointer returns NULL...
exit(1);
}
// reads text until a newline is encountered...
fscanf(fptr, "%[^\n]", c);
printf("Data from the file:\n%s", c);
// Convert the file to upper case....
for( i=0;i<= strlen(c);i++){
if(c[i]>=65&&c[i]<=90)
c[i]=c[i]+32;
}
fptr = fopen("program.txt","w");
fprintf(fptr,"%[^\n]",c);
fclose(fptr);
return 0;
}
Edit: added #include <stdlib.h>, removed static describing main()
My proposition, based on example of copying a file given at my uni.
I used toupper() from ctype.h, if you don't want to use it you can just add 32 under condition similarly to your solution
Note: there could be char c instead of int c. (In the original version it actually was char; I changed it because if you look at the headers in the docs of all functions dealing with c, they all take/return int, not char; in your version it would matter more as you keep an array, in my program it changes pretty much nothing – int is just my preferred practice).
Note2: I actually never delved into the difference between "w"/"r" (write/read) and "wb"/"rb" (write/read binary). The code seems to work either way.
(I think there is no big difference when the files are text files anyway, for further assurance that both versions work, note that the code uses feof() to handle EOF)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
FILE *from, *to;
int c;//could be char
/* opening the source file */
if ((from = fopen("text.txt", "rb")) == NULL) {
printf("no such source file\n");
exit(1);
}
/* opening the target file */
if ((to = fopen("program.txt", "wb")) == NULL) {
printf("error while opening target file\n");
exit(1);
}
while (!feof(from)) {
c = fgetc(from);
if (ferror(from)) {
printf("error while reading from the source file\n");
exit(1);
}
if (!feof(from)) {//we avoid writing EOF
fputc(toupper(c), to);
if (ferror(to)) {
printf("error while writing to the target file\n");
exit(1);
}
}
}
if (fclose(from) == EOF) {
printf("error while closing...\n");
exit(1);
}
if (fclose(to) == EOF) {
printf("error while closing...\n");
exit(1);
}
return 0;
}
For a version taking arguments from command line (works on windows too) replace the beginning of main with
int main(int argc, char *argv[]) {
FILE *from, *to;
char c;
/* checking the number of arguments in the command line */
if (argc != 3) {
printf("usage: name_of_executable_of_this_main <f1> <f2>\n");//name_of_exe could be copy_to_upper, for example; change adequately
exit(1);
}
/* opening the source file */
if ((from = fopen(argv[1], "rb")) == NULL) {
printf("no such source file\n");
exit(1);
}
/* opening the target file */
if ((to = fopen(argv[2], "wb")) == NULL) {
printf("error while opening the target file\n");
exit(1);
}
I don't know how to code in that language(i think it's C++), but basically want you should be doing is a for loop to iterate through every character in the string. In Python it would look like:
x = open("text.txt", "r")
y = open("new text.txt","w")
z = ""
for char in x:
z += char.upper()
y.write(z)
I hope I was able to give an idea of how to solve your problem. I'm a newbie as well, but in Python.

need help My Library project has member problem

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

Can't get fwrite to work properly

I'm trying to write a program that is able to open a text file and split it so I can save it in two new ones to save files faster. But with the code I have now I'm not able to print the chars that I pick from the orignal file to the new ones.
In my text file I have the text "Dutch people are tall".
In my new files I want to get:
File 1: Dthpol r tl
File 2: uc epeaeal
This is the code I have got so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char cUsb1;
char cUsb2;
char str[128];
FILE *ptr_readfile;
FILE *ptr_usb1;
FILE *ptr_usb2;
ptr_readfile = fopen("Dutch People.txt","r"); // open readfile
while(ptr_readfile != NULL) // keep running while readfile != null
{
if (ptr_readfile != EOF) // keep running while readfile != eof
{
cUsb1 = fgetc(ptr_readfile); // to get a char out of the readfile
ptr_usb1 = fopen("USB1.txt", "w"); // create and open USB1 file
fwrite(cUsb1 , str , str , ptr_usb1); //writing get c to file
cUsb2 = fgetc(ptr_readfile); // to get a char out of the readfile
ptr_usb2 = fopen("USB2.txt", "w"); // create and open USB2 file
fwrite(cUsb2 , str , str, ptr_usb2); //writing get c to file
fclose(ptr_usb1); // closing the file
fclose(ptr_usb2); // closing the file
}
break; // to stop the while loop
fclose(ptr_readfile); // closing the file
}
return 0;
}
Many things are not quite right. You need to look carefully through the warnings reported by the compiler - enable all warnings if possible (e.g. "-Wall") - and resolve them all. Then single-step through your program with a debugger until it does something you didn't expect.
As a starting point, instead of:
fwrite(cUsb1 , str , str , ptr_usb1);
you might mean
fwrite(&cUsb1 , 1 , 1 , ptr_usb1);
There should be a warning for that line to tell you that you shouldn't try to pass cUsb1 (a char) as the first parameter of fwrite, as that parameter expects a pointer, i.e. an address of something. Use &cUsb1 to mean "the address of cUsb1".
You can use fputc for writing one character at a time. Also the while loop is not needed.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
int i = 0;
FILE *ptr_readfile = NULL;
FILE *ptr_usb1 = NULL;
FILE *ptr_usb2 = NULL;
ptr_readfile = fopen("Dutch People.txt", "r"); // open readfile
if (ptr_readfile != NULL) {
ptr_usb1 = fopen("USB1.txt", "w"); // create and open USB1 file
ptr_usb2 = fopen("USB2.txt", "w"); // create and open USB2 file
if (ptr_usb1 != NULL && ptr_usb2 != NULL) {
while ((c = fgetc(ptr_readfile)) != EOF) {
if (i % 2 == 0) {
fputc(c, ptr_usb1);
}
else {
fputc(c, ptr_usb2);
}
i++;
}
}
fclose(ptr_readfile); // closing the file
}
if (ptr_usb1 != NULL) {
fclose(ptr_usb1);
}
if (ptr_usb2 != NULL) {
fclose(ptr_usb2);
}
return 0;
}

How do I remove SEGFAULT here?

I created a function to print the contents of a file:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
where file is a global variable. GDB gives output as follows:
_IO_getc (fp=0x0) at getc.c:39
39 getc.c: No such file or directory.
(gdb) bt
#0 _IO_getc (fp=0x0) at getc.c:39
#1 0x000000000040075e in readFile ()
#2 0x00000000004006d4 in main ()
However, the file is present and I get the SEGFAULT after printing the contents of the file. It might be because the buffer here (c) is small but I am not sure. Also, I don't know how do I fix this even if that were the case. Can anyone suggest how do I proceed?
EDIT
I call the readFile function only once. Here is my calling function:
int main(int argc, char* argv[])
{
char * filename;
filename = argv[1];
readFile(filename);
printf("File Handler: %ld", (long)file);
fclose(file);
return 0;
}
You're passing in a filename that doesn't exist or for some other reason cannot be opened. Get rid of the segfault by checking for errors (you'll need to #include <errno.h> and <string.h> too for this:
void readFile(char* filename)
{
int c ;
file = fopen(filename, "r");
if (file == NULL) {
printf("Cannot open file '%s' : %s\n", filename, strerror(errno));
return;
}
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
printf("%c", c);
}
return;
}
Most likely your file is NULL and you are still trying to read it.
I simulated this behaviour (SEG fault) when I deleted this file.
If file exists then your code works fine.
Check what path you are passing.. If you are using single \ try with \\ and see if this works. First \ will work as escape sequence and final path will be send as D:\temp\use.dat to fopen.
readFile("D:\\temp\\user.dat");
Before you do anything with a file, you must ensure that you opened it successfully. This is done by checking that the file pointer received by calling fopen is not NULL.
Once you do this, you read using whatever function you choose until it returns a value that indicates failure to read — a NULL pointer for fgets, 0 or EOF for fscanf, or EOF for fgetc.
In any case, you challenge these return values in two ways. The first way is to check for read errors using ferror. The other way is to check whether the end of the file was reached using feof.
A complete program that should work, based upon your code:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
enum { OPEN_ERROR = 1, READ_ERROR };
enum { PARAM_EXIT = 1, OPEN_EXIT, READ_EXIT };
FILE *file = NULL;
int readFile(char* filename)
{
int c;
file = fopen(filename, "r");
if (file == NULL)
return OPEN_ERROR;
printf("The contents of file '%s' are:\n", filename);
while((c = fgetc(file)) != EOF)
printf("%c", c);
/*
* fgetc returns EOF on end of file and when an error occurs.
* feof is used to determine whether the end of the file was reached.
* Otherwise, we encountered a read error.
*/
if (feof(file))
c = 0;
else
c = READ_ERROR;
return c;
}
int main(int argc, char *argv[])
{
int status = 0;
if (argc == 1) {
fprintf(stderr, "usage: %s file\n", argv[0]);
return PARAM_ERROR;
}
/* Check that <program ""> wasn't used... */
if (argv[1][0] == '\0') {
fprintf(stderr, "error: empty filename detected, exiting. . .\n");
return PARAM_ERROR;
}
switch (readFile(argv[1])) {
case 0:
break;
case OPEN_ERROR:
fprintf(stderr, "error: file open failed - %s\n", strerror(errno));
status = OPEN_EXIT;
break;
case READ_ERROR:
fprintf(stderr, "error: file read failed - %s\n", strerror(errno));
status = READ_EXIT;
break;
default:
fprintf(stderr, "error: unknown error occurred, aborting...\n");
abort();
}
if (file != NULL)
fclose(file);
return status;
}
Of course, normally you would close the file in the same function in which it was opened (e.g. something like filep = openFile(...); readFile(filep); fclose(filep);, except error handling would be used of course).
I am completely changing my answer
Actually, the file that I was reading was open in gedit (which might explain why I was getting "NULL" even after printing the file contents. I closed the file and removed my NULL comparison code and it works perfectly fine.
Ok, from everybody's comments I got to know that you basically get a SEGFAULT when you read the contents of file that has NULL contents. I just made a simple fix in my while loop:
while((c != EOF))
{
printf("%c", c);
c = fgetc(file);
if(c == NULL)
break;
}
Problemo solved! (Although, the compiler gives me a warning of "comparison between pointer and integer".)

Resources