read file txt in langage c - 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 :

Related

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.

realloc : corrupted data returned

I'm trying to read from a file using C and after shrinking the size using realloc I get corrupted data. I don't really see what the problem could be.
Here's the function that returns the string :
char *read_string(FILE *fichier) {
char car = 0;
size_t size = 1;
char *symbole = realloc(NULL, sizeof(char) * size);
char *s;
size_t len = 0;
if (!symbole)
return symbole;
else
s = symbole;
do {
car = getc(fichier);
} while (car != '"' && car != EOF);
if (car == EOF)
return EOFP;
else {
car = getc(fichier);
while (car != '"' ) {
s[len] = car;
car = getc(fichier);
len++;
if (len == size) {
symbole = realloc(s, sizeof(char) * (size += 1));
if (!symbole)
return symbole;
else
s = symbole;
}
}
s[len] = '\0' ;
symbole = realloc(s, sizeof(char) * len);
if (!symbole) {
printf("WTF");
return symbole;
} else
s = symbole;
return s;
}
}
My main function is:
int main(int argc, char *argv[]) {
FILE *fichier = NULL;
fichier = fopen("C:/Users/Nabila K/Documents/test.json", "r");
if ((fichier != NULL)) {
while (feof(fichier) == 0) {
char *test = read_string(fichier);
if (test == NULL) {
printf("test == NULL\n");
exit(1);
} else
if (test == EOFP) {
} else {
printf("%s\n", test);
free(test);
}
}
fclose(fichier);
} else {
exit(EXIT_FAILURE);
}
return 0;
}
UPDATE
My json file looks something like this :
{
"KARIM BENNI" : {
"2017-08-07 09:50:50" : {
"Anomalie" : {
"description" : "Test",
"theme" : "Engins mobiles"
},
"date" : "2017-08-07",
"date_now" : "2017-08-07 09:50:50",
"entite" : "USINE LAMINAGE A FROID",
"etat" : "Cree",
"nb_personne" : 2,
"temps" : 5,
"visiteur" : "KARIM BENNI",
"visite" : "AHMED RABII",
"zone" : "COUPE"
}
}
}
There are multiple issues in your code:
char car = 0; is incorrect: you must define car as int to correctly distinguish all values returned by getc(), especially EOF.
while (feof(fichier) == 0) is always wrong. Learn why there: Why is “while ( !feof (file) )” always wrong?
EOFP is not defined, you should probably use NULL instead for more clarity.
the final realloc() to shrink the allocated block is one byte too short. You must keep len+1 bytes for len characters plus the null terminator.
Here is a simplified and corrected version:
#include <stdio.h>
#include <stdlib.h>
char EOFP[1]; /* special value used to signal end of file */
char *read_string(FILE *file) {
int c;
size_t size, len;
char *symbol;
char *s;
while ((c = getc(file)) != '"') {
if (c == EOF)
return EOFP;
}
size = 16;
len = 0;
symbol = malloc(size);
if (symbol == NULL) {
/* allocation failure */
return NULL;
}
while ((c = getc(file)) != '"') {
if (c == EOF) {
/* premature end of file in the middle of a string */
free(symbol);
return EOFP;
}
if (len + 2 < size) {
size += size;
s = realloc(symbol, size);
if (s == NULL) {
/* allocation failure */
free(symbol);
return NULL;
}
symbol = s;
}
symbol[len++] = c;
}
symbol[len] = '\0';
s = realloc(symbol, len + 1);
return s ? s : symbol;
}
int main(int argc, char *argv[]) {
FILE *file = fopen("C:/Users/Nabila K/Documents/test.json", "r");
if (file != NULL)) {
char *test;
while ((test = read_string(file)) != EOFP) {
if (test == NULL) {
printf("test == NULL\n");
exit(1);
} else {
printf("%s\n", test);
free(test);
}
}
fclose(file);
} else {
exit(EXIT_FAILURE);
}
return 0;
}
Notes:
Parsing the full JSON syntax for strings would be required if the strings can contain escaped characters such as \" or \n, \\ etc.

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.

Program Printing Unnecessary 'ÿ' Character

My program compares two text files and puts the differences in file one in a third text file. However, when my file one's size is larger than my file two's size a 'ÿ' character is placed at the end of the third file. For example suppose file one consists of "I like pickles." and file two consists of "I like dogs." then the third file will consist of "pickles.ÿ". Is there a way to get rid of this? And why is this happening? Here is my program:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int ch1, ch2;
int size1, size2;
FILE *fh1, *fh2, *diffone=stdout;
if( argc<3 ) {
printf("need two file names\n"); return(1);
}
if(!(fh1 = fopen(argv[1], "r"))) {
printf("cannot open %s\n",argv[1]); return(2);
}
if(!(fh2 = fopen(argv[2], "r"))) {
printf("cannot open %s\n",argv[2]); return(3);
}
if(argc>3) {
if(!(diffone = fopen(argv[3], "w+"))) {
printf("cannot open %s\n",argv[3]); return(4);
}
}
fseek(fh1, 0, SEEK_END);
size1 = ftell(fh1);//gets size of fh1
fseek(fh1, 0, SEEK_SET);
fseek(fh2, 0, SEEK_END);
size2 = ftell(fh2);//gets size of fh2
fseek(fh2, 0, SEEK_SET);
while((!feof(fh1)) || (!feof(fh2)))
{
ch1=ch2='-';
if(!feof(fh1)) ch1 = getc(fh1);
if(!feof(fh2)) ch2 = getc(fh2);
if (size2 > size1)
{
if(ch1 != ch2 && (!feof(fh1)))
{
fprintf(diffone,"%c", ch1);
}
}
else
{
if (ch1 != ch2)
{
fprintf(diffone,"%c", ch1);
}
}
}
}
feof() only returns true after fgetc() has returned EOF (-1).
See Why is “while ( !feof (file) )” always wrong?
You are not doing any error checking on fgetc(), and you are not checking for EOF on fh2 when size1 > size2.
Try this instead:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int ch1, ch2;
int eof1 = 0, eof2 = 0;
FILE *fh1, *fh2, *diffone=stdout;
if (argc < 3) {
printf("need two file names\n");
return(1);
}
if (!(fh1 = fopen(argv[1], "r"))) {
printf("cannot open %s\n",argv[1]);
return(2);
}
if (!(fh2 = fopen(argv[2], "r"))) {
printf("cannot open %s\n",argv[2]);
return(3);
}
if (argc > 3) {
if (!(diffone = fopen(argv[3], "w+"))) {
printf("cannot open %s\n",argv[3]);
return(4);
}
}
while(1)
{
if (!eof1) {
ch1 = fgetc(fh1);
if (ch1 == EOF) {
if (ferror(fh1)) {
printf("cannot read from %s\n",argv[1]);
return(5);
}
eof1 = 1;
}
}
else {
ch1 = '-';
}
if (!eof2) {
ch2 = fgetc(fh2);
if (ch2 == EOF) {
if (ferror(fh2)) {
printf("cannot read from %s\n",argv[2]);
return(6);
}
eof2 = 1;
}
}
else {
ch2 = '-';
}
if ((eof1) && (eof2))
break;
if ((ch1 != ch2) || (eof1 != eof2)) {
if (fputc(ch1, diffone) == EOF) {
if (argc > 3) {
printf("cannot write to %s\n",argv[3]);
}
return(7);
}
}
}
return 0;
}
Check EOF after each fgetc().
Avoid using feof(). Recall feof() becomes true after an EOF was first returned from a read.
Instead of
while((!feof(fh1)) || (!feof(fh2))) {
if(!feof(fh1)) ch1 = getc(fh1);
if(!feof(fh2)) ch2 = getc(fh2);
Use
while (1) {
ch1 = fget(fh1);
ch2 = fget(fh2);
if (ch1 == EOF) {
if (ch2 == EOF) break;
ch1 = '-';
}
if (ch2 == EOF) {
ch2 = '-';
}
....
}
This problem occurs when you are trying to fetch from file first and then print
for example-
ch=fgetc(fp2);
while(ch!=EOF)
{
ch = fgetc(fp2);
fputc(ch, fp1);
}
INSTEAD DO-
ch=fgetc(fp2);
while(ch!=EOF)
{
fputc(ch, fp1);
ch = fgetc(fp2);
}

Finding and checking a file extension

I read the other articles for finding the file extension from a filename in C and I've tried them but the problem is that they don't work correctly.
This is my code :
void optionOne()
{
char filenameSrc[101],filenameDest[101];
strcpy(filenameSrc,"");
do
{
printf("Enter source filename (*.c) : ");
scanf("%s",filenameSrc);
}while (check_file_ext(filenameSrc) != 0);
fflush(stdout);
printf("Enter destination filename : ");
scanf("%s",&filenameDest);
char line[80];
FILE* fp = fopen("data.inp","r");
while(fgets(line,sizeof(line),fp))
{
// do something
}
fclose(fp);
}
and the function check_file_ext :
const char *get_file_ext(const char *filename)
{
const char *dot = strrchr(filename, '.');
if(!dot || dot == filename) return "";
return dot + 1;
}
int check_file_ext(const char* filename)
{
return strcmp(get_file_ext(filename),"c") == 0;
}
The problem is in the check method for the file extension?
Could you tell me where is the problem in the code?
Don't return "", return a pointer to '\0' byte instead:
// gcc -std=c99
#include <stdio.h>
#include <string.h>
static const char*
get_file_ext(const char *filename) {
const char *ext = strrchr(filename, '.');
return (ext && ext != filename) ? ext : (filename + strlen(filename));
}
int main() {
char *files[] = {"a.c", ".a", "a", NULL };
for (char** f = files; *f != NULL; ++f)
printf("ext: '%s'\n", get_file_ext(*f));
}
Note: it ncludes . in the extension for consistency.
Output
ext: '.c'
ext: ''
ext: ''
Reverse condition: do{ ... }while(strcmp(get_file_ext(filename), ".c") != 0);

Resources