How to fprintf on file with recursive - c

I'm a newbie with recursion. How do I fopen and fclose a file in a recursive function?
void make(LINK lis, char *name, int flag, FILE *f)
{
if (lis == NULL) {
fclose(f);
}
else {
if (flag == 0) {
FILE *f = fopen(name, "w");
flag = 1;
}
else {
fprintf(f, "CODICE: %d\n", lis->d.codice);
make(lis->next, name, 1, f);
}
}
}
My goal is to recursively write "codice" --> CODE in a file.

Your most immediate problem is that on the first call, you open the file and then return to the main program, without processing anything. Opening the file should be a simple test, not an if-then-else.
void make(LINK lis, char *name, FILE *f)
{
if (!lis) {
fclose(f);
}
else {
if (f) {
f = fopen(name, "w");
}
fprintf(f, "CODICE: %d\n", lis->d.codice);
make(lis->next, name, f);
}
}
}

How do I fopen and fclose a file in a recursive function?
Be sure to do so at the same level of recursion.
Consider first how the nth and first would look separately:
void make_nth(LINK lis, FILE *outf) {
if (lis) {
fprintf(outf, "CODICE: %d\n", lis->d.codice);
make_nth(lis->next, outf);
}
}
void make_1st(LINK lis, const char *name) {
FILE *f = fopen(name, "w");
if (f) {
make_nth(lis, f);
fclose(f);
}
}
// Usage
LINK lis = ...;
make_1st(lis, codice.txt);
Now put that together. Various ways exist to do this.
void make(LINK lis, const char *name, FILE *outf) {
if (name) {
assert(outf == NULL);
FILE *f = fopen(name, "w");
if (f) {
make(lis, NULL, f);
fclose(f);
}
} else {
if (lis) {
fprintf(outf, "CODICE: %d\n", lis->d.codice);
make(lis->next, NULL, outf);
}
}
}
// Usage
LINK lis = ...;
make(lis, codice.txt, NULL);

Related

read file txt in langage c

it's a cesar encrypt in process
the problem is when i open a file with the method "openFile"
/* it's been 2 years since I've touched the c language, I'm getting back to it */
i have this code other file :
//method to encrypt a char
char encrypt(char c, int jump) {
int overflow = 0;
char res = c;
char tabChars[26] = {'a','b','c','d','e','f','g','h',
'i','j','k','l','m','n','o','p','q',
'r','s','t','u','v','w','x','y','z'};
for(int i=0;i<sizeof (tabChars);i++) {
if(c == tabChars[i]) {
if(i+jump > 25) {
overflow = i+jump - 26;
res = tabChars[overflow];
} else if(i+jump <= 25) {
res = tabChars[i+jump];
}
}
}
return res;
};
void writeInFile(FILE* file) {
//todo
};
// error here
void openFile(char* file) {
FILE* f = fopen(file, "r");
printf("\nopen file : %s\n", file);
char c;
while((c = getc(f)) != EOF) {
putchar(c);
}
fclose(f);
};
and main code :
int jump = 5;
char c = 't';
printf("\nletter change with : --%c--\n",encrypt(c,jump));
char* file = "taget/to/message.txt";
openFile(file); // error here
but i have a error :
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
why doesn't work ? thanks all
with if(f) // works, thx all for your comments
void openFile(char* file) {
FILE* f = fopen(file, "r");
if(f) {
printf("\nopen file : %s\n", file);
char c;
while((c = getc(f)) != EOF) {
putchar(c);
}
fclose(f);
} else {
printf("\nopen error...\n");
}
};
out of function :

I don't know why the file won't open

This is my code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct {
int M,N;
int min,max;
int width;
int height;
unsigned char **pixels;
}PPMIMG;
int fnReadPPM(char* fileNm,PPMIMG* img);
int main(int argc, char ** argv)
{
PPMIMG img;
if(fnReadPPM(argv[1], &img) != FALSE)
{
return TRUE;
}
return 0;
}
int fnReadPPM(char* fileNm ,PPMIMG* img)
{
FILE* fp;
fp = fopen("/users/ashton/Downloads/test.txt","rb");
if(fileNm == NULL){
fprintf(stderr,"Unable to File ! : %s\n",fileNm);
return FALSE;
}
fclose(fp);
return TRUE;
}
int fnWritePPM(char* fileNm, PPMIMG* img)
{
FILE *fp =fopen(fileNm, "w");
if(fp == NULL)
{
fprintf(stderr, "Failed to create the file.");
return FALSE;
}
return TRUE;
}
This is the error code:
Unable to File ! : (null)
Program ended with exit code: 0
Your wrongly test the fopen return value:
fp = fopen("/users/ashton/Downloads/test.txt","rb");
if (fp == NULL) { //<===== Was WRONG, you used fileNm instead of fp
perror("Unable to File");
return FALSE;
}
The problem ist most likely here:
int fnReadPPM(char* fileNm ,PPMIMG* img)
{
FILE* fp;
fp = fopen("/users/ashton/Downloads/test.txt","rb"); // you assign fp
if (fileNm == NULL){ // and here you check for fileNm
fprintf(stderr,"Unable to File ! : %s\n",fileNm);
return FALSE;
}
...
You want this:
int fnReadPPM(char* fileNm ,PPMIMG* img)
{
FILE* fp;
fp = fopen("/users/ashton/Downloads/test.txt","rb");
if (fp == NULL) {
fprintf(stderr,"Unable to open file %s.\n", fileNm);
return FALSE;
}
...
However in the fnWritePPM function you did it right.

How to test if a file is open/closed in different functions in C

I need to write separate functions for opening/closing the file and working with it. Was recommended to not use global variables in it.
I have a function where I need to open the file and print what's in it(open_file), a second to work with the data in it(do_stuff_in_file), and a third to only close the file and exit the program(close_file).
When I try to call do_stuff_in_file or close_file the program just crashes.
I know I'm supposed to use pointers, but I just can't get it right and I don't know where's the mistake.
int open_file(FILE **fr) {
if ((fr = fopen("soldcars.txt", "r")) == NULL) {
printf("File was not opened\n");
return 1;
}
else {
char testchar;
while ((testchar = fgetc(fr)) != EOF) {
ungetc(testchar, fr);
//just printing whats in the file
}
}
return 0;
}
int do_stuff_in_file(FILE **fr, int date) {
if (fr==NULL) {
printf("File not open yet\n");
return 1;
}
else{ fseek(fr, 0, SEEK_SET); } //doing stuff
return 0;
}
int close_file(FILE **fr) {
if (fr==NULL) {
printf("It was not even open yet\n");
return 1;
}
else{
if (fclose(fr) == EOF) {
printf("File was not successfully closed");
return 1;
}
else{
printf("Adios");
exit(1);
}
}
}
int main() {
char input;
int date;
FILE* fr;
fr = NULL;
while ((input = getchar()) != 'c') {
if (input == 'o') open_file(&fr);
else if (input == 'd') {
scanf("%d", &date);
do_stuff_in_file(&fr, date);
}
}
if (input == 'c') {
close_file(&fr);
}
return 0;
}
You need to dereference properly. eg
int open_file(FILE **fr) {
if ((*fr = fopen("soldcars.txt", "r")) == NULL) {
perror( "soldcars.txt" );
return 1;
}
Note *fr = open instead of fr = open. And, in that function, always use *fr, as in fgetc(*fr) vice fgetc(fr). Similarly in the other functions. Because fr is not a FILE *, but *fr is.

How to remove newline from between strings read from another text file

char IP[32] = "";
char PORT[4] = "0000";
int read_conf()
{
int i;
char line[25] = "";
FILE *fp;
char *str_ptr;
fp = fopen("client.conf","r");
for(i=1;(fgets(line,sizeof(line),fp));i++)
{
if(1==i)
{
str_ptr = strstr(line,"IP:");
if(str_ptr)
{
strcpy(IP,(str_ptr+3));
}
else
{
printf("Error in fetching IP \n");
exit(0);
}
}
else if(2==i)
{
str_ptr = strstr(line,"Port:");
if(str_ptr)
{
strcpy(PORT,(str_ptr+5));
}
else
{
printf("Error in fetching PORT \n");
exit(0);
}
}
}
return 1;
}
char *construct_url(int n,char * const argv[])
{
char * final_url;
int i,k=2;
int j = 0;
final_url = malloc(sizeof(char *)*300);
strcpy(final_url,"http://");
strcat(final_url,IP);
strcat(final_url,":");
strcat(final_url,PORT);
strcat(final_url,"/");
//printf("%s",final_url);
for(i=1;i<n,k>0;i++,k--)
{
strcat(final_url,argv[i]);
if(i==1)
{
strcat(final_url,"/");
}
else
{
strcat(final_url,"?");
}
}
return final_url;
}
In my above code it is adding a newline after IP and PORT value which is not correct URL construction. how do I avoid new line before concatenation.
client.conf consist
IP:10.12.130.216
Port:5200
Expected Result:
http://10.12.130.216:5200/
Getting Result:
http://10.12.130.216
:5200
/
read_conf can be written in simple as follows using fscanf.
char PORT[6] = "00000";//0-65535
int read_conf(void){
FILE *fp = fopen("client.conf","r");
if(1 != fscanf(fp, "IP:%31s\n", IP)){
printf("Error in fetching IP \n");
exit(0);
}
if(1 != fscanf(fp, "Port:%5s", PORT)){
printf("Error in fetching PORT \n");
exit(0);
}
fclose(fp);
return 1;
}
If you are sure that it is a new line, use:
strcat(final_url,IP);
strtok(final_url, "\n");
strcat(final_url,":");
strcat(final_url,PORT);
strtok(final_url, "\n");
strcat(final_url,"/");
or use strtock function separately for IP and PORT strings.

Sorting array filled with lines of string

I have a data in text like this:
1,jack,3,7.3
2,mike,4,8.6
3,gol,2,9
Could any one help me how to sort the data by the last column that represent the grades in descending using c language?
The question was posted before but with no code so I posted it again to get more help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int cid;
char name[40];
char term[2];
double gpa;
}student;
typedef struct
{
char line[300];
}data;
typedef struct
{
int cid;
}finds;
typedef struct
{
double score;
}gpa;
void menu();
int calculateMax(void);
void addStudent();
void find();
void display();
void sort();
int main()
{
menu();
system("PAUSE");
return 0;
}
void menu()
{
int selection;
printf("%s", "Program menu :\n");
printf("%s", "1. Add a new student\n");
printf("%s", "2. Find/retrieve information for a particular Student\n");
printf("%s", "3. Display STUDENTS list\n");
printf("%s", "4. Find a student that has the lowest and the highest deposit\n");
printf("%s", "5. Quit\n");
printf("%s", "Selection : ");
scanf("%d", &selection);
if(selection == 1)
{
addStudent();
}
else if(selection == 2)
{
find();
}
else if(selection == 3)
{
display();
}
else if(selection == 4)
{
sort();
}
else if(selection == 5)
{
exit(0);
}
else {
printf("%s", "\n\aError, please key in correct input!\n\n");
menu();
}
}
void addStudent()
{
int max, i;
FILE *f, *id, *name, *term, *gpa , *sort;
printf("%s", "\n\nADD student\n");
printf("%s", "How many students you would like to add : ");
scanf("%d", &max);
student *student_info;
student_info = (student *) malloc(max * sizeof(student)); /*Allocate Memory For Client's Info*/
if(student_info == NULL)
{
printf("Unable to allocate space for client\n\n");
exit (EXIT_FAILURE);
}
if ((id = fopen("id.txt", "a+")) == NULL) /*Open file id.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((name = fopen("name.txt", "a+")) == NULL) /*Open file name.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((term = fopen("term.txt", "a+")) == NULL) /*Open file TERM.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((gpa = fopen("gpa.txt", "a+")) == NULL) /*Open file GPA.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((f = fopen("student.txt", "a+")) == NULL) /*Open file STUDENTS.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((sort = fopen("sort.txt", "a+")) == NULL) /*Open file SORT.txt*/
{
printf("Error, the file cannot be opened\n");
}
else {
for (i = 0; i < max ; i++) { /*Get the input data*/
printf("student %d\n", i + 1);
printf("%s", "student's Id : ");
scanf("%5d", &student_info[i].cid);
printf("%s", "student's Name : ");
fflush(stdin);
gets(student_info[i].name);
printf("%s", "student's term : ");
fflush(stdin);
gets(student_info[i].term);
printf("%s", "student's GPA : ");
scanf("%7lf", &student_info[i].gpa);
printf("\n");
}
}
for(i = 0; i < max; i++) { /*Store input data into files*/
fprintf(id, "%d\n", student_info[i].cid);
fputs(student_info[i].name, name);
fprintf(name, "\n");
fputs(student_info[i].term, term);
fprintf(term, "\n");
fprintf(gpa, "%lf\n", student_info[i].gpa);
fprintf(sort,"%d,%s,%s,%lf\n",student_info[i].cid,student_info[i].name,student_info[i].term,student_info[i].gpa);
}
for(i = 0; i < max; i++) {
fprintf(f, "%d", student_info[i].cid, "");
fprintf(f, "%3s", "");
fputs(student_info[i].name, f);
fprintf(f, "%5s", "");
fputs(student_info[i].term, f);
fprintf(f, "%7s", "");
fprintf(f, "%lf\n", student_info[i].gpa);
}
fclose(f);
fclose(id);
fclose(name);
fclose(term);
fclose(gpa);
fclose(sort);
free(student_info);
student_info = NULL;
printf("\n");
menu();
}
void find()
{
int find_id = 0, i = 0, student_cid, n = 0, max, selection;
FILE *id, *f;
max = calculateMax();
finds *result;
result = (finds *) malloc(max * sizeof(finds));
if(result == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((id = fopen("id.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
else {
while (!feof(id)) { /*Get all clients' id number and store to array*/
fscanf(id, "%d", &result[i].cid);
i++;
}
}
fclose(id);
printf("%s", "\n\nFIND STUDENT\n");
printf("%s", "Key in Student's id : "); /*Get the client's id that user want to query*/
scanf("%d", &student_cid);
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) { /*Get all the students' data from clients.txt and stored to array*/
fflush(stdin);
fgets(student_info[i].line, 300, f);
i++;
}
fclose (f);
for(i = 0; i < max + 1; i++)
{
if(student_cid == result[i].cid)
{
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
puts(student_info[i].line);
free(student_info);
student_info = NULL;
free(result);
result = NULL;
printf("Would you like to find another student?\nKey in 1 for yes or 2 to go to menu : ");
scanf("%d",&selection);
if(selection == 1) {
find();
}
else if(selection == 2) {
menu();
}
break;
}
else if(i == max)
{
printf("\nSory, there's no student with that exist in database.\n");
free(student_info);
student_info = NULL;
free(result);
result = NULL;
printf("Would you like to find another student?\nKey in 1 for yes or 2 to go to menu : ");
scanf("%d",&selection);
if(selection == 1) {
find();
}
else if(selection == 2) {
printf("\n\n");
menu();
}
}
}
}
void display()
{
int max = 0, i;
FILE *f;
printf("\n\nDISPLAY STUDENT");
max = calculateMax();
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) {
fflush(stdin);
fgets(student_info[i].line, 200, f);
i++;
}
fclose (f);
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
for(i = 0; i < max; i++)
{
puts(student_info[i].line);
}
free(student_info);
student_info = NULL;
}
int calculateMax(void)
{
char str[150];
int maximum = 0;
FILE *f;
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
else {
while (!feof(f)) {
maximum++;
fgets (str , 200 , f);
}
}
fclose (f);
maximum = maximum - 1;
return maximum;
}
////////////////////////////////////////////////////////////////////
static int student_info_compare(const void *a, const void *b)
{
const student_info *sia = a, *sib = b;
return strcmp(sia->name, sib->name);
}
void Sortdisplay()
{
int max = 0, i;
FILE *f;
printf("\n\nDISPLAY SORTED STUDENT");
max = calculateMax();
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("sort.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) {
fflush(stdin);
fgets(student_info[i].line, 200, f);
i++;
}
fclose (f);
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
student_info_compare();
for(i = 0; i < max; i++)
{
// iwant to sort here
qsort(student_info, max, sizeof student_info[0], student_info_compare);
puts(student_info[i].line);
}
free(student_info);
student_info = NULL;
}
Try this:
static int student_info_compare(const void *a, const void *b)
{
const student_info *sia = a, *sib = b;
return strcmp(sia->name, sib->name);
}
then add this before the print loop:
qsort(student_info, max, sizeof student_info[0], student_info_compare);
This uses the standard qsort() function to sort the array. The student_info_compare() function serves as the comparison-callback, since qsort() doesn't know how your data looks.
The arguments to the comparison-callback have type const void *, which basically means "here's a pointer to something whose exact type is not known, and you're supposed to treat it as a read-only pointer". That's how qsort() passes pointers to the array elements, since (again) it doesn't know that they are of type const student_info *.

Resources