I read a file and stock all characters like this:
void ReadFile()
{
int c;
FILE *file;
int string_size;
file = fopen("/userFiles/ex.txt", "r");
char * content;
if (file)
{
// Seek the last byte of the file
fseek(file, 0, SEEK_END);
// Offset from the first to the last byte, or in other words, filesize
string_size = ftell(file);
// go back to the start of the file
rewind(file);
// Allocate a string that can hold it all
content = malloc((string_size + 1) * sizeof(char));
int i = 0;
while ((c = getc(file)) != EOF)
{
//printf("%c",(char) c);
content[i] = (char) c;
i++;
}
content[string_size] = '\0';
printf("content: %s",content);
fclose(file);
}
else
{
printf("not load\n");
}
}
Problem is if i read each carachter i've got the content of the file but if i do:
printf("content: %s",content);
I got just a symbol and not text whereas i need to pass the content var with correct text in argument of a json reply.
This is the first line of the file (CRC32):
�ex.txt k��X� ?xml version="1.0" encoding="utf-8"?
I compiled and ran the following code and it shows no major problem when executed.
The compilable version I used is (cmdline: gcc main.c -Wall -Wextra -o main):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
int c;
FILE *file;
int string_size;
file = fopen("plop", "r");
char * content;
if (file == NULL)
{
perror("fprintf");
return 1;
}
// Seek the last byte of the file
fseek(file, 0, SEEK_END);
// Offset from the first to the last byte, or in other words, filesize
string_size = ftell(file);
// go back to the start of the file
rewind(file);
// Allocate a string that can hold it all
content = malloc((string_size + 1) * sizeof(char));
int i = 0;
while ((c = getc(file)) != EOF)
{
//printf("%c",(char) c);
content[i] = (char) c;
i++;
}
content[string_size] = '\0';
printf("content: %s", content);
return 0;
}
Maybe your file has a binary content?
What is the symbol printed, that you mentioned?
I think you should use quotes "" around the content string:
printf("content: \"%s\"",content);
Related
I am new to C, After 4 days, I finally managed to make a program that read a file and remove space from it. I need to also make it parallel using MPI in any way. I tried various solutions, but MPI does not seem straightforward, it is complex, can someone please help me a bit to move forward.
Here is my code. It first reads a text file, and then removes space and new line characters.
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
FILE* pInputFile;
int chr = 0;
int main()
{
FILE* fptr;
char c;
char filename[] = "Lorem.txt";
char* str, * strblank;
int i = 0;
errno_t err;
if ((err = fopen_s(&pInputFile, filename, "r")) == 0)
{
/*count the number of characters in file for file initialization*/
size_t pos = ftell(pInputFile); // Current position
fseek(pInputFile, 0, SEEK_END); // Go to end
size_t length = ftell(pInputFile); // read the position which is the size
fseek(pInputFile, pos, SEEK_SET); // restore original position
//creating dynamic array of file size
str = malloc(length * sizeof(char));
strblank = malloc(length * sizeof(char));
while ((chr = getc(pInputFile)) != EOF)
{
str[i] = chr;
i++;
}
i = 0;
printf("%s", str);
removespace(str, strblank);
printf("%s", strblank);
fclose(pInputFile);
}
else
{
fprintf(stderr, "Cannot open file, error %d\n", err);
}
return 0;
}
int removespace(char aj[500], char mj[500])
{
int i = 0, j = 0, len;
len = strlen(aj); // len stores the length of the input string
while (aj[i] != '\0') // till string doesn't terminate
{
if (aj[i] != ' ' && aj[i] != '\n') // if the char is not a white space
{
/*
incrementing index j only when
the char is not space
*/
mj[j++] = aj[i];
}
/*
i is the index of the actual string and
is incremented irrespective of the spaces
*/
i++;
}
mj[j] = '\0';
printf("\n\nThe string after removing all the spaces is: ");
return 0;
}
I am trying to read the contents of a file and copy those contents into a string which has dynamic memory. However my program keeps allocating only 8 bytes to x. Ultimately I'm trying to create a general function that can read contents from a file and then return the contents as a char. Any help is appreciated.
char* readFile(unsigned long size, char *fileName) {
FILE *file = fopen(fileName, "r");
int c;
if(file != NULL)
{
while(c != EOF){ //calculate size of file
c = fgetc(file); //store character
size++;
}
char *x = (char *)malloc((size) * (sizeof(char))); // Size of x = 8 and I'm not sure why
rewind(file);
printf("\n");
int i = 0;
while(size - 1 > i){ //Reading the files contents to the allocated string
c = fgetc(file); //store character
if(c == EOF){
break;
}
x[i] = c;
i++;
}
fclose(file);
printf("Done Reading");
}
else
{
printf("\nError: Unable to open the file for Reading.\n");
}
rewind(file);
return 0;
}
I get a segmentation fault when I run
char* str = readFile(size, originalFile);
I would use stat to first get the size of your file
stat() retrieves information about the file pointed
to by pathname;
And then I made some tiny modifications to your function to make it work:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
char* readFile(char *fileName) {
FILE *file;
struct stat st;
if (!(file = fopen(fileName, "r")))
return NULL;
stat(fileName, &st);
unsigned long size = st.st_size;
char *x;
if (!(x = (char *)malloc((size + 1) * (sizeof(char))))) // Size of x = 8 and I'm not sure why
return NULL;
unsigned long i = 0;
while (i < size) //Reading the files contents to the allocated string
x[i++] = getc(file);
x[i] = '\0';
fclose(file);
printf("Done Reading\n");
return x;
}
int main(void) {
char *fileName = "a.txt";
char *res = readFile(fileName);
printf("%s\n", res);
return 0;
}
Don't forget that in C strings are NULL terminated, you need to malloc size+1 to add the final '\0'.
This is (IMHO) an easier way to find the size of the file:
char *readFile(const char *fileName)
{
unsigned long size = 0;
char *x;
FILE *file = fopen(fileName, "r");
int c;
if (file != NULL)
{
fseek(file, 0, SEEK_END); /* SET the position at EOF */
size = ftell(file); /* Record the position at EOF to return size of file */
rewind(file); /* SET position back to Origin */
printf("size detected %ld\n", size); // reads correct size
x = (char *)malloc((size) * (sizeof(char)));
rewind(file);
printf("\n");
int i = 0;
while (size - 1 > i)
{ //Reading the files contents to the allocated string
c = fgetc(file); //store character
if (c == EOF)
{
break;
}
x[i] = c;
i++;
}
fclose(file);
printf("Done Reading\n");
}
else
{
printf("\nError: Unable to open the file for Reading.\n");
return NULL;
}
rewind(file);
return x; // * you need to return x not zero
}
Successfully reads the content of the file:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *data;
data = readFile("records.txt");
printf("%s\n", data);
return 0;
}
In my code I'm trying to read a file, read it's lines and get them into a String array, then print them and close the file. When I run it, it fails on a seg fault and skips the last line of the file, and I just can't find the problem...
My instinct is to blame reading the array wrongly or misbehaving with the file... Am I right?
Any help or redirects would be helpful.
Thank you!
Here is the main file:
#include "files_utils.h"
int main()
{
FILE *fp = fopen("expl", "r");
if (!fp)
return -1;
long lines_count = countlines(fp);
long flen = file_length(fp);
String *lines = calloc(lines_count, sizeof(String));
printf("file length: %ld\n", flen);
printf("file lines: %ld\n", lines_count);
getlines(lines, lines_count, fp);
printf("finished\n");
for (String *sp = lines; sp != NULL; sp++)
printf("%s", *sp);
printf("before close\n");
fclose(fp);
printf("closed\n");
return 0;
}
Here is the files_utils file:
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 10
typedef char *String;
long file_length(FILE *fp)
{
/*
find the length of the file fp points to, regardless of the current position.
*/
long original_pos = ftell(fp), i = 0;
rewind(fp);
// count chars:
for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
i++;
// return the file to it's original position
fseek(fp, original_pos, SEEK_SET);
return i;
}
long countlines(FILE *fp)
{
/*
find the amount of lines in file fp points to, regardless of the current position.
*/
long original_pos = ftell(fp), i = 0;
rewind(fp);
// find newlines:
for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
if (c == '\n')
i++;
// return the file to it's original position
fseek(fp, original_pos, SEEK_SET);
return i;
}
String *getlines(String lines[], long maxlines, FILE *fp)
{
for (int i = 0; i <= maxlines; i++)
{
lines[i] = calloc(MAXLINE, sizeof(char));
fgets(lines[i], MAXLINE, fp);
}
return lines;
}
And it outputs
file length: 144
file lines: 21
finished
... all the lines of the file except of the last one ...
Segmentation fault (core dumped)
The problem was fixed when I changed the printing loop to run until maxlines instead of waiting for NULL. Why is this? Why would waiting for NULL raise a seg fault?
Is there any way to navigate through a file with the option of moving up and down the line number instead of sequentially?
As of now, my code uses fgets to get the last line of ascii characters within the file, but through my research, I haven't found a smarter way of iterating through the file.
For example:
file.txt contains:
"hello\n"
"what's up?\n"
"bye"
I need to be able to return "bye" at first, but then using key presses, print "what's up\n", and go back down to "bye" through another key press.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *infile;
char *infile_contents;
unsigned int infile_size;
// to read all of the file
infile = fopen("file.txt", "rb");
fseek(infile, 0, SEEK_END);
infile_size = ftell(infile);
fseek(infile, 0,SEEK_SET);
infile_contents = malloc(infile_size+1);
fread(infile_contents, infile_size, 1, infile);
fclose(infile);
infile_contents[infile_size]=0;
// to store the beginning of lines and replace '\n' with '\0'
size_t num_lines = 1, current_line = 1, length;
char **lines = malloc(sizeof(char*)), **lines1, *tmp;
lines[0] = infile_contents;
while(tmp = strchr(infile_contents, '\n'))
{
// to resize lines if it is not big enough
if(num_lines == current_line)
{
lines1 = lines;
lines = malloc((num_lines<<1)*sizeof(char*));
memcpy(lines, lines1, num_lines*sizeof(char*));
memset(lines+num_lines, 0, num_lines*sizeof(char*));
num_lines <<= 1;
free(lines1);
}
*tmp=0;
infile_contents = tmp+1;
lines[current_line++] = infile_contents;
}
// to print the lines
num_lines = current_line-1;
current_line = num_lines;
// to skip the last line if it is empty
if(!lines[current_line][0])
{
num_lines--;
current_line = num_lines;
}
while(1)
{
printf("%s",lines[current_line]);
if(getchar())// change to the condition for going down
{
if(current_line)
current_line--;
else
current_line=num_lines;
}
else
{
if(current_line==num_lines)
current_line=0;
else
current_line++;
}
}
}
#include <stdio.h>
#include <stdlib.h>
int count_arr(FILE *file)
{
int c,count=0;
//FILE *file;
//file = fopen("test.txt", "r");
if (file) {
while ((c = getc(file)) != EOF){
putchar(c);
++count;}
fclose(file);
}
return count;
}
void make_arr (FILE *file, char arr[]){
int c,n=0,count=0;
char ch;
//FILE *file;
//file = fopen("test.txt", "r");
if (file) {
while ((c = getc(file)) != EOF){
ch = (char)c;
arr[n]=ch;
++n; }
fclose(file);
}
}
int main(){
FILE *file;
int n;
//scanf("%c",&file_name);
file = fopen("test.txt","r");
int count = count_arr(file);
char arr [count];
make_arr(file, arr);
for(n=0; n<count;++n) printf("%c",arr[n]);
}
So far this is all I have for my code. I know I am doing it completely wrong. When I print out the char array it prints random junk... I am trying to code a function "make_arr" that passes an array which gets stored with characters from a file. Any help would be appreciated!
Here is an small example that reads a file into a buffer:
FILE* file = fopen("file.txt", "r");
// get filesize
fseek(file, 0, SEEK_END);
int fsize = ftell(file);
fseek(file, 0, SEEK_SET);
// allocate buffer **note** that if you like
// to use the buffer as a c-string then you must also
// allocate space for the terminating null character
char* buffer = malloc(fsize);
// read the file into buffer
fread(buffer, fsize, 1, file);
// close the file
fclose(file);
// output data here
for(int i = 0; i < fsize; i++) {
printf("%c", buffer[i]);
}
// free your buffer
free(buffer);
If you really would like to use a function to fill your buffer this would work (not really see the point though), although I still will make only one read operation:
void make_array(FILE* file, char* array, int size) {
// read entire file into array
fread(array, size, 1, file);
}
int main(int argc,char** argv) {
// open file and get file size by first
// moving the filepointer to the end of the file
// and then using ftell() to tell its position ie the filesize
// then move the filepointer back to the beginning of the file
FILE* file = fopen("test.txt", "r");
fseek(file, 0, SEEK_END);
int fs = ftell(file);
fseek(file, 0, SEEK_SET);
char array[fs];
// fill array with content from file
make_array(file, array, fs);
// close file handle
fclose(file);
// output contents of array
for(int i = 0; i < fs; i++) {
printf("%c\n", array[i]);
}
return 0;
}
Like I stated in the comments above you need to add space for the terminating null character if you like to use the char array as a string:
char* array = malloc(fs + 1);
fread(array, fs, 1, file);
// add terminating null character
array[fs] = '\0';
// print the string
printf("%s\n", array);