C Programming Read file and store it as a string [duplicate] - c

This question already has answers here:
Reading the whole text file into a char array in C
(5 answers)
Closed 8 years ago.
I wrote c code which input value for my program comes from here :
char *input[] = {"This input string value !!!", NULL};
But how can I read this value from the file (e.g. input.txt)? Is it possible to get the file content like a string?
Thanks a lot!

If you want to read a file line-by-line, the easiest way to go is using getline. Read the man page for a detailed description and a good code example.
getline will do all the low-lvel plumbing work of allocating buffers, copying data and scanning for newline characters, etc for you. Keep in mind that this is only possible since getline uses dynamically allocated memory that you'll need to free again.

On recent Posix compliant systems you could use getline(3), something like
FILE *fil = fopen("somefile.txt", "r");
if (!fil) {perror("somefile.txt"); exit(EXIT_FAILURE); };
char*linbuf = NULL;
size_t siz = 0;
ssize_t linlen = 0;
while ((linlen=getline(&linbuf, &siz, fil))>0) {
// linbuf contains the current line
// linlen is the length of the current line
do_something_with(linbuf, linlen);
};
fclose(fil);
free(linbuf), linbuf=NULL;
linlen = 0, siz = 0;

You can use fgets() like this:
#include <stdio.h>
int main(void)
{
char buffer[100];
FILE *file = fopen("input.txt", "r");
// Checks if the file was opened successfully
if (file == NULL)
{
fputs("Failed to open the file\n", stderr);
return -1;
}
// fgets here reads an entire line or 99 characters (+1 for \0) at a time, whichever comes first
while (fgets(buffer, sizeof(buffer), file) != NULL)
{
printf("Line read = %s\n", buffer);
}
fclose(file);
}
You can also use fgetc() like this:
#include <stdio.h>
int main(void)
{
int ch;
FILE *file = fopen("input.txt", "r");
// Checks if the file was opened successfully
if (file == NULL)
{
fputs("Failed to open the file\n", stderr);
return -1;
}
// fgetc reads each character one by one until the end of the file
while ((ch = fgetc(file)) != EOF)
{
printf("Character read = %c\n", ch);
}
fclose(file);
}

Related

Printing the first 10 line of a file in C

I'm new to programming in C. And I'm trying to print the first 10 lines of a text file. When I run my program with a text file containing 11 lines of text, only the first line is displayed. I'm not sure why it does that, but I suspect there is something wrong in my while loop. Can someone please help me?
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *myfile;
char content;
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL){
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
content = fgetc(myfile);
while (content != EOF){
max++;
if (max > 10)
break;
printf ("%c", content);
content = fgetc(myfile);
}
fclose(myfile);
return 0;
}
You have been already advised to use fgets. However, if your file has lines of unknown length, you may still want to use fgetc. Just make sure you count only newlines, not all characters:
int max = 0;
int content;
while ((content = fgetc(myfile)) != EOF && max < 10){
if (content == '\n') max++;
putchar(content);
}
fgetc() returns the next character in the file, not the next line. You probably want to use fgets() instead, which reads up to the next newline character into a buffer. Your code should probably end up with something like:
// allocate 1K for a buffer to read
char *buff = malloc(1024);
// iterate through file until we are out of data or we read 10 lines
while(fgets(buff, 1024, myfile) != NULL && max++ < 10) {
printf("%s\n", buff);
}
free(buff);
// close your file, finish up...
Read more about fgets() here: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
fgetc function reads the next character not the next ine. for reading the number of lines you should use fgets function. this function reads the full string till the end of the one line and stores it in a string.
your code Shuld be as:-
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *myfile;
char content[200];
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL)
{
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
fgets(content, 200, myfile);
while (content != EOF)
{
max++;
if (max > 10)
break;
printf("%s", content);
fgets(content, 200, myfile);
}
fclose(myfile);
return 0;
}

Opening Files in C

Full Edit:
I am getting frustrated, I don't know what am I doing wrong in here
I still have so many stuff to do in the code but I can't even open a file to continue my work.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main()
{
char letter;
FILE *fp;
fp=fopen("‪‪‪C:\\Users\\LENOVO\\Desktop\\data.txt","r");
if(fp==NULL)
{
printf("error");
getch();
exit(1);
}
while(fscanf(fp,"%d",&letter)!=EOF)
putchar(letter);
getch();
fclose(fp);
}‪
Picture of the path: http://imgur.com/a/YwFYy
Still prints error
Ok, firstly let's take a look at your file path. There are two ways to acces a file from your local storage:
relative addresses if the file has the same root folder as your application
absolute addresses if the file is in a determined place on your machine's storage
I see that you are trying to use an absolute address to read from your file. Your path is correct but you have to take care about string formatting in C because the \ character could be interpreted as something else.
I would suggest to use this instead ( double back-slash )
input=fopen("‪C:\\Users\\LENOVO\\Desktop\\data.txt","r");
This will prevent string formatting interpretations.
Secondly, EOF is just a predefined macro constant and i think it is equal to -1 so your while(! (-1) ) code is not a good ideea for reading until the end of the file.
In order to read from a file until you reach the its end i would consider this property of fscanf() :
fscanf() returns EOF when it reaches the end of the file.
while(fscanf(input,"%ch",&letter) != EOF) {
putchar(letter);
}
This way of reading from a file should do the job.
To read everything from a text file and store its contents into a buffer:
First, you should count how many characters there are in the text file:
size_t get_file_len(FILE *fp)
{
size_t num = 0;
while (fgetc(fp) != EOF)
num++;
return (fseek(fp, 0, SEEK_SET) == 0 ? num : 0);
}
Then allocate memory for a buffer large enough and read all the characters:
char *load_text(const char *path)
{
char *buf = NULL;
FILE *fp = NULL;
size_t num = 0;
size_t i = 0;
int c = 0;
/* open the file in text mode */
fp = fopen(path, "r");
if (!fp)
return NULL;
/* if the file was empty or if an error occurred, return error */
if ((num = get_file_len(fp)) == 0) {
fclose(fp);
return NULL;
}
buf = malloc(num + 1);
if (!buf) {
fclose(fp);
return NULL;
}
while ((c = fgetc(fp)) != EOF)
buf[i++] = (char)c;
/* ensure that the string is null-terminated */
buf[i] = '\0';
fclose(fp);
return buf;
}
Also, in C, all escape sequences begin with a '\' (backslash), so if you wanted to write a backslash in a string or a char you should write it as a '\\' (double backslash):
input=fopen("‪C:\\Users\\LENOVO\\Desktop\\data.txt","r");
pretty simple here :
while(!feof(input)){
fscanf(input,"%c",&letter);
putchar(letter);
}
and remember to close file using fclose(input);

Reading a File as Strings

I want to read the data of the file into a string.
Is there a function that reads the whole file into a character array?
I open the file like this:
FILE *fp;
for(i = 0; i < filesToRead; i++)
{
fp = fopen(name, "r");
// Read into a char array.
}
EDIT: So how to read it "line by line" getchar() ?
Here are three ways to read an entire file into a contiguous buffer:
Figure out the file length, then fread() the whole file. You can figure out the length with fseek() and ftell(), or you can use fstat() on POSIX systems. This will not work on sockets or pipes, it only works on regular files.
Read the file into a buffer which you dynamically expand as you read data using fread(). Typical implementations start with a "reasonable" buffer size and double it each time space is exhausted. This works on any kind of file.
On POSIX, use fstat() to get the file and then mmap() to put the entire file in your address space. This only works on regular files.
You can do the following:
FILE *fp;
int currentBufferSize;
for(i = 0; i < filesToRead; i++)
{
fp = fopen(name, "r");
currentBufferSize = 0;
while(fp != EOF)
fgets(filestring[i], BUFFER_SIZE, fp);
}
Of course you would have to make this in a more robust way, checking if your buffer can hold all the data and so on...
You might use something like the following: where you read each line, carefully check the result and pass it to a datastructure of your choosing. I have not shown how to properly allocate memory, but you can malloc up front and realloc when necessary.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define FILE_BUFFER_SIZE 1024
int file_read_line(FILE *fp, char *buffer)
{
// Read the line to buffer
if (fgets(buffer, FILE_BUFFER_SIZE, fp) == NULL)
return -errno;
// Check for End of File
if (feof(fp))
return 0;
return 1;
}
void file_read(FILE *fp)
{
int read;
char buffer[FILE_BUFFER_SIZE];
while (1) {
// Clear buffer for next line
buffer[0] = '\0';
// Read the next line with the appropriate read function
read = file_read_line(fp, buffer);
// file_read_line() returns only negative numbers when an error ocurred
if (read < 0) {
print_fatal_error("failed to read line: %s (%u)\n",
strerror(errno), errno);
exit(EXIT_FAILURE);
}
// Pass the read line `buffer` to whatever you want
// End of File reached
if (read == 0)
break;
}
return;
}

In C, how should I read a text file and print all strings

I have a text file named test.txt
I want to write a C program that can read this file and print the content to the console (assume the file contains only ASCII text).
I don't know how to get the size of my string variable. Like this:
char str[999];
FILE * file;
file = fopen( "test.txt" , "r");
if (file) {
while (fscanf(file, "%s", str)!=EOF)
printf("%s",str);
fclose(file);
}
The size 999 doesn't work because the string returned by fscanf can be larger than that. How can I solve this?
The simplest way is to read a character, and print it right after reading:
int c;
FILE *file;
file = fopen("test.txt", "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
c is int above, since EOF is a negative number, and a plain char may be unsigned.
If you want to read the file in chunks, but without dynamic memory allocation, you can do:
#define CHUNK 1024 /* read 1024 bytes at a time */
char buf[CHUNK];
FILE *file;
size_t nread;
file = fopen("test.txt", "r");
if (file) {
while ((nread = fread(buf, 1, sizeof buf, file)) > 0)
fwrite(buf, 1, nread, stdout);
if (ferror(file)) {
/* deal with error */
}
fclose(file);
}
The second method above is essentially how you will read a file with a dynamically allocated array:
char *buf = malloc(chunk);
if (buf == NULL) {
/* deal with malloc() failure */
}
/* otherwise do this. Note 'chunk' instead of 'sizeof buf' */
while ((nread = fread(buf, 1, chunk, file)) > 0) {
/* as above */
}
Your method of fscanf() with %s as format loses information about whitespace in the file, so it is not exactly copying a file to stdout.
There are plenty of good answers here about reading it in chunks, I'm just gonna show you a little trick that reads all the content at once to a buffer and prints it.
I'm not saying it's better. It's not, and as Ricardo sometimes it can be bad, but I find it's a nice solution for the simple cases.
I sprinkled it with comments because there's a lot going on.
#include <stdio.h>
#include <stdlib.h>
char* ReadFile(char *filename)
{
char *buffer = NULL;
int string_size, read_size;
FILE *handler = fopen(filename, "r");
if (handler)
{
// Seek the last byte of the file
fseek(handler, 0, SEEK_END);
// Offset from the first to the last byte, or in other words, filesize
string_size = ftell(handler);
// go back to the start of the file
rewind(handler);
// Allocate a string that can hold it all
buffer = (char*) malloc(sizeof(char) * (string_size + 1) );
// Read it all in one operation
read_size = fread(buffer, sizeof(char), string_size, handler);
// fread doesn't set it so put a \0 in the last position
// and buffer is now officially a string
buffer[string_size] = '\0';
if (string_size != read_size)
{
// Something went wrong, throw away the memory and set
// the buffer to NULL
free(buffer);
buffer = NULL;
}
// Always remember to close the file.
fclose(handler);
}
return buffer;
}
int main()
{
char *string = ReadFile("yourfile.txt");
if (string)
{
puts(string);
free(string);
}
return 0;
}
Let me know if it's useful or you could learn something from it :)
Instead just directly print the characters onto the console because the text file maybe very large and you may require a lot of memory.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *f;
char c;
f=fopen("test.txt","rt");
while((c=fgetc(f))!=EOF){
printf("%c",c);
}
fclose(f);
return 0;
}
Use "read()" instead o fscanf:
ssize_t read(int fildes, void *buf, size_t nbyte);
DESCRIPTION
The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor, fildes, into the buffer pointed to by buf.
Here is an example:
http://cmagical.blogspot.com/2010/01/c-programming-on-unix-implementing-cat.html
Working part from that example:
f=open(argv[1],O_RDONLY);
while ((n=read(f,l,80)) > 0)
write(1,l,n);
An alternate approach is to use getc/putc to read/write 1 char at a time. A lot less efficient. A good example: http://www.eskimo.com/~scs/cclass/notes/sx13.html
You can use fgets and limit the size of the read string.
char *fgets(char *str, int num, FILE *stream);
You can change the while in your code to:
while (fgets(str, 100, file)) /* printf("%s", str) */;
Two approaches leap to mind.
First, don't use scanf. Use fgets() which takes a parameter to specify the buffer size, and which leaves any newline characters intact. A simple loop over the file that prints the buffer content should naturally copy the file intact.
Second, use fread() or the common C idiom with fgetc(). These would process the file in fixed-size chunks or a single character at a time.
If you must process the file over white-space delimited strings, then use either fgets or fread to read the file, and something like strtok to split the buffer at whitespace. Don't forget to handle the transition from one buffer to the next, since your target strings are likely to span the buffer boundary.
If there is an external requirement to use scanf to do the reading, then limit the length of the string it might read with a precision field in the format specifier. In your case with a 999 byte buffer, then say scanf("%998s", str); which will write at most 998 characters to the buffer leaving room for the nul terminator. If single strings longer than your buffer are allowed, then you would have to process them in two pieces. If not, you have an opportunity to tell the user about an error politely without creating a buffer overflow security hole.
Regardless, always validate the return values and think about how to handle bad, malicious, or just malformed input.
You can use getline() to read your text file without worrying about large lines:
getline() reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character, if one was found.
If *lineptr is set to NULL before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.
bool read_file(const char *filename)
{
FILE *file = fopen(filename, "r");
if (!file)
return false;
char *line = NULL;
size_t linesize = 0;
while (getline(&line, &linesize, file) != -1) {
printf("%s", line);
free(line);
}
free(line);
fclose(file);
return true;
}
You can use it like this:
int main(void)
{
if (!read_file("test.txt")) {
printf("Error reading file\n");
exit(EXIT_FAILURE);
}
}
I use this version
char* read(const char* filename){
FILE* f = fopen(filename, "rb");
if (f == NULL){
exit(1);
}
fseek(f, 0L, SEEK_END);
long size = ftell(f)+1;
fclose(f);
f = fopen(filename, "r");
void* content = memset(malloc(size), '\0', size);
fread(content, 1, size-1, f);
fclose(f);
return (char*) content;
}
You could read the entire file with dynamic memory allocation, but isn't a good idea because if the file is too big, you could have memory problems.
So is better read short parts of the file and print it.
#include <stdio.h>
#define BLOCK 1000
int main() {
FILE *f=fopen("teste.txt","r");
int size;
char buffer[BLOCK];
// ...
while((size=fread(buffer,BLOCK,sizeof(char),f)>0))
fwrite(buffer,size,sizeof(char),stdout);
fclose(f);
// ...
return 0;
}

Correct way to read a text file into a buffer in C? [duplicate]

This question already has answers here:
How to read the content of a file to a string in C?
(12 answers)
Closed 5 years ago.
I'm dealing with small text files that i want to read into a buffer while i process them, so i've come up with the following code:
...
char source[1000000];
FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
while((symbol = getc(fp)) != EOF)
{
strcat(source, &symbol);
}
fclose(fp);
}
...
Is this the correct way of putting the contents of the file into the buffer or am i abusing strcat()?
I then iterate through the buffer thus:
for(int x = 0; (c = source[x]) != '\0'; x++)
{
//Process chars
}
char source[1000000];
FILE *fp = fopen("TheFile.txt", "r");
if(fp != NULL)
{
while((symbol = getc(fp)) != EOF)
{
strcat(source, &symbol);
}
fclose(fp);
}
There are quite a few things wrong with this code:
It is very slow (you are extracting the buffer one character at a time).
If the filesize is over sizeof(source), this is prone to buffer overflows.
Really, when you look at it more closely, this code should not work at all. As stated in the man pages:
The strcat() function appends a copy of the null-terminated string s2 to the end of the null-terminated string s1, then add a terminating `\0'.
You are appending a character (not a NUL-terminated string!) to a string that may or may not be NUL-terminated. The only time I can imagine this working according to the man-page description is if every character in the file is NUL-terminated, in which case this would be rather pointless. So yes, this is most definitely a terrible abuse of strcat().
The following are two alternatives to consider using instead.
If you know the maximum buffer size ahead of time:
#include <stdio.h>
#define MAXBUFLEN 1000000
char source[MAXBUFLEN + 1];
FILE *fp = fopen("foo.txt", "r");
if (fp != NULL) {
size_t newLen = fread(source, sizeof(char), MAXBUFLEN, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0'; /* Just to be safe. */
}
fclose(fp);
}
Or, if you do not:
#include <stdio.h>
#include <stdlib.h>
char *source = NULL;
FILE *fp = fopen("foo.txt", "r");
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { /* Error */ }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0'; /* Just to be safe. */
}
}
fclose(fp);
}
free(source); /* Don't forget to call free() later! */
Yes - you would probably be arrested for your terriable abuse of strcat !
Take a look at getline() it reads the data a line at a time but importantly it can limit the number of characters you read, so you don't overflow the buffer.
Strcat is relatively slow because it has to search the entire string for the end on every character insertion.
You would normally keep a pointer to the current end of the string storage and pass that to getline as the position to read the next line into.
If you're on a linux system, once you have the file descriptor you can get a lot of information about the file using fstat()
http://linux.die.net/man/2/stat
so you might have
#include <unistd.h>
void main()
{
struct stat stat;
int fd;
//get file descriptor
fstat(fd, &stat);
//the size of the file is now in stat.st_size
}
This avoids seeking to the beginning and end of the file.
See this article from JoelOnSoftware for why you don't want to use strcat.
Look at fread for an alternative. Use it with 1 for the size when you're reading bytes or characters.
Why don't you just use the array of chars you have? This ought to do it:
source[i] = getc(fp);
i++;
Not tested, but should work.. And yes, it could be better implemented with fread, I'll leave that as an exercise to the reader.
#define DEFAULT_SIZE 100
#define STEP_SIZE 100
char *buffer[DEFAULT_SIZE];
size_t buffer_sz=DEFAULT_SIZE;
size_t i=0;
while(!feof(fp)){
buffer[i]=fgetc(fp);
i++;
if(i>=buffer_sz){
buffer_sz+=STEP_SIZE;
void *tmp=buffer;
buffer=realloc(buffer,buffer_sz);
if(buffer==null){ free(tmp); exit(1);} //ensure we don't have a memory leak
}
}
buffer[i]=0;
Methinks you want fread:
http://www.cplusplus.com/reference/clibrary/cstdio/fread/
Have you considered mmap()? You can read from the file directly as if it were already in memory.
http://beej.us/guide/bgipc/output/html/multipage/mmap.html

Resources