I am reading a text file and trying to display its contents on the console. Here is my code:
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <fstream>
int main()
{
FILE* fp=NULL;
char buff[100];
fp=fopen("myfile.txt","r");
if(fp==NULL)
{
printf("Couldn't Open the File!!!\n");
}
fseek(fp, 0, SEEK_END);
size_t file_size = ftell(fp);
fread(buff,file_size,1,fp);
printf("Data Read [%s]",buff);
fclose(fp);
return 0;
}
but only redundant data is being displayed on the console; could someone please point out my mistake?
You forgot to reset the file pointer to start after doing this.
fseek(fp, 0, SEEK_END);
Do this after finding size (file_size).
rewind (fp);
You need to seek back to the start of the file before reading:
int main()
{
FILE* fp=NULL;
char buff[100];
fp=fopen("myfile.txt","r");
if(fp==NULL)
{
printf("Couldn't Open the File!!!\n");
exit(1); // <<< handle fopen failure
}
fseek(fp, 0, SEEK_END);
size_t file_size = ftell(fp);
fseek(fp, 0, SEEK_SET); // <<< seek to start of file
fread(buff,file_size,1,fp);
printf("Data Read [%s]",buff);
fclose(fp);
return 0;
}
Try it....
#include <stdio.h>
#include <stdlib.h>
void handle_line(char *line) {
printf("%s", line);
}
int main(int argc, char *argv[]) {
int size = 1024, pos;
int c;
char *buffer = (char *)malloc(size);
FILE *f = fopen("myfile.txt", "r");
if(f) {
do { // read all lines in file
pos = 0;
do{ // read one line
c = fgetc(f);
if(c != EOF) buffer[pos++] = (char)c;
if(pos >= size - 1) { // increase buffer length - leave room for 0
size *=2;
buffer = (char*)realloc(buffer, size);
}
}while(c != EOF && c != '\n');
buffer[pos] = 0;
// line is now in buffer
handle_line(buffer);
} while(c != EOF);
fclose(f);
}
free(buffer);
return 0;
}
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <fstream>
int main()
{
FILE* fp=NULL;
char *buff; //change array to pointer
fp=fopen("myfile.txt","r");
if(fp==NULL)
{
printf("Couldn't Open the File!!!\n");
}
fseek(fp, 0, SEEK_END);
size_t file_size = ftell(fp);
buff = malloc(file_size); //allocating memory needed for reading file data
fseek(fp,0,SEEK_SET); //changing fp to point start of file data
fread(buff,file_size,1,fp);
printf("Data Read [%s]",buff);
fclose(fp);
return 0;
}
having a buffer of 100 bytes to read a file is not a better idea as since the file size may be more than 100 bytes.
A better file io can be done by doing a fgets on the file, if its not a type of metadata that you wanted to read using the fread.
fgets in a while loop can be used to check whether its reached EOF or a feof call can be used to check the EOF.
a sample code listing of fgets can be like this:
while (fgets(buf, len, fp)) {
printf("%s", buf);
}
or a sample that is used with fgets can be like this:
while (fread(buf, len, 1, fp) >= 0) {
printf("%s\n", buf);
}
Related
If I have a file which contains a '\n' on virtually every line, and I use getline() in a while loop to read the content, is this bad practice?
My understanding is that getline() will be called numerous times for each '\n' char reached, and so realloc() will be called each time also. Which seems inefficient?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
perror("Unable to open file: ");
exit(1);
}
char *buffer = NULL;
size_t len = 0;
ssize_t characters;
while ((characters = getline(&buffer, &len, fp)) != -1) {
fputs(buffer, stdout);
}
fclose(fp);
free(buffer);
buffer = NULL;
return 0;
}
There is no problem calling getline in a loop as you do. As a matter of fact, this exactly the intended use case and used in the example in the man page.
realloc is only called if the array allocated so far is too short for the current line, thus it will be called very little and you can even lower the number of calls by allocating an initial array and set its length in the len variable.
Since getline returns the number of characters read, you could write the line using fwrite instead of fputs. Note however that the behavior is subtly different: fwrite will output lines read from the file containing embedded null bytes, whereas fputs would stop on the first null byte. This is usually not an issue as text files usually do not contain null bytes.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
fprintf(stderr, "Unable to open file %s: %s\n",
"file.txt", strerror(errno));
return 1;
}
char *buffer = NULL;
size_t len = 0;
ssize_t characters;
#if 1
// optional code to show how to start with a preallocated buffer
if ((buffer = malloc(256)) != NULL)
len = 256;
#endif
while ((characters = getline(&buffer, &len, fp)) != -1) {
fwrite(buffer, 1, characters, stdout);
}
fclose(fp);
free(buffer);
return 0;
}
#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);
I tried cyclically read file in buffer of 100 byte.
When i read file first time - buffer was full. Returned value is 0. No error and no eof (functions "ferror" and "feof" shows no error). Then i tried read file second time and again returned value is 0, no error and no eof. But then i have empty buffer. I don't know what is the problem?
if(fopen_s(&file_in, argv[1], "rb") == 0){
printf("File was opened.\n");
while(!feof(file_in)){
read_code = fread_s(file_data, 100, sizeof(unsigned char), 100, file_in);
if(ferror(file_in)) {
printf("Error!\n");
}
if(feof(file_in)) {
printf("Eof!\n");
}
printf("Read result: %d\n", read_code);
/*Using the buffer*/
memset(file_data, 0, 100);
}
fclose(file_in);
}
For the reasons given in comments regarding fopen_s, et. al., Here is an alternative implementation of reading a binary file using getc(), along with fopen(), fclose(), etc. (I am not using a Microsoft implementation, but am using ANSI C99)
It has a commented section I used to create a test binary file. Other than that it sizes the file you are reading so you can allocate the right amount of memory, then reads the binary data into a buffer.
For navigating your file, take a look at fseek() with its stdio.h defined arguments:
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
In this example, everything is closed or freed before exiting:
#include <windows.h>
#include <ansi_c.h>
long int getFileSizeFromPath(char * path)
{
FILE * file;
long int fileSizeBytes = 0;
file = fopen(path,"r");
if(file){
fseek(file, 0, SEEK_END);
fileSizeBytes = ftell(file);
fseek(file, 0, SEEK_SET);
fclose(file);
}
return fileSizeBytes;
}
int main(int argc, char *argv[])
{
FILE *fp=0;
char *binBuf;
long int size=0;
int i=0;
int byte=0;
//create 100 byte test file (c:\\dev\\tessst.bin)
// fp = fopen(argv[1], "wb");
//
// srand(clock());
// for(i=0;i<100;i++)
// {
// byte = rand();
// putc(byte, fp);
// }
// putc(EOF, fp);
//
// fclose(fp);
size = getFileSizeFromPath(argv[1]);
binBuf = calloc(size + 1, sizeof(char));
fp = fopen(argv[1], "rb");
byte = getc(fp);
while(byte != EOF)
{
binBuf[i++] = (char)byte;
byte = getc(fp);
}
fclose(fp);
free(binBuf);
return 0;
}
iv'e written a part of a code which basically transfers text from a txt file into a variable and prints it(as a part of a program),yet it does not print the contents at all.
#include <stdio.h>
#include <stdlib.h>
#define WRONG_ARGUMENTS (-1)
int Lines(FILE * file);
int Length(FILE * file);
int Read(FILE * file);
int Lines(FILE * file)
{
int c=0,count=0;
++count;
while(c!=EOF)
{
c=fgetc(file);
if(c=='\n')
++count;
}
return count;
}
int Length(FILE * file)
{
int c,count=0;
while((c=fgetc(file))!=EOF)
{
++count;
}
return count;
}
int Reader(FILE * Text,char * File)
{
int counter=0;
while(fscanf(Text,"%s",File)!=EOF)
{
++counter;
strcat(File," ");
}
return counter;
}
int main(int argc,char * argv[]) {
FILE * Text=NULL;
if(argc!=2)
{
printf("usage:library text dictionary\n");
return -1;
}
Text = fopen(argv[1],"r");
if(Text==NULL)
{
printf("file %s could not be opened\n",argv[1]);
return -1;
}
char * File = "";
File=malloc(Length(Text)*(sizeof(char)));
int r = Reader(Text,File);
printf(File);
return 0;
}
i will be more than glad to understand the problem in the partial code
the output is x>
thanks,
Consider the following cut-down example. You'll notice that the getFileLength function (a) doesn't actually read anything from the file and (b) makes use of the fseek and ftell functions - fseek is the function that you use to reposition the file-pointer when it reaches EOF.
Imagine that you weren't printing the data, but doing something else with it. What if the file is a billion bytes long? We sure don't want to read 1,000,000,000 times from it just to determine its length!
As for the use of calloc - it zero initializes the data it allocates. Since you're reading text, you want to ensure that the text is NULL-terminated. (NULL generally = 0, though I've seen evil macros that change this) This NULL terminator is also why I allocate 1 byte more than the file contains.
#include <stdio.h>
#include <stdlib.h>
long getFileLength(FILE *input)
{
long result;
long origPos = ftell(input);
fseek(input, 0, SEEK_END);
result = ftell(input);
fseek(input, origPos, SEEK_SET);
return result;
}
int main (void)
{
FILE *fp;
long fileLen, numBytesRead;
char *data;
fp = fopen("main.cpp", "rb");
fileLen = getFileLength(fp);
data = (char*)calloc(sizeof(char), fileLen+1);
numBytesRead = fread(data, sizeof(char), fileLen, fp);
if (numBytesRead != fileLen)
printf("Error reading all bytes from file. Expected: %d, Read %d\n", fileLen, numBytesRead);
else
printf("%s", data);
free(data);
fclose(fp);
}
I was wondering how I can get this code to overwrite a textfile from it's text value to it's ASCII value.
I want it to do something like this:
CMD > c:\users\username\desktop>cA5.exe content.txt
content.txt has "abc" in it and I want the command line to change the "abc" to it's ASCII values. 97... etc. I don't want anything written in the command window, I want it to change in the text file. Is this possible, if so, how could I do it with this existing code?
#include <stdio.h>
#include <stdlib.h>
int main(int argc[1], char *argv[1])
{
FILE *fp; // declaring variable
fp = fopen(argv[1], "rb");
if (fp != NULL) // checks the return value from fopen
{
int i;
do
{
i = fgetc(fp); // scans the file
printf("%c",i);
printf(" ");
}
while(i!=-1);
fclose(fp);
}
else
{
printf("Error.\n");
}
}
Not the best code but very simple.
#include <stdio.h>
#include <stdlib.h>
void convertToAHex(char *data, long int size, FILE *file){
rewind(file);
int i;
for(i = 0; i < size; ++i){
fprintf(file, "%d ", data[i]);
}
}
int main(int argc, char *argv[]){
if(argc != 2){
return EXIT_FAILURE;
}
FILE *file = fopen(argv[1], "r+");
if(file){
char *data;
long int size;
fseek(file, 0, SEEK_END);
size = ftell(file);
rewind(file);
data = (char *) calloc(size, sizeof(char));
if(data){
fread(data, 1, size, file);
convertToAHex(data, size, file);
free(data);
}
fclose(file);
}
return EXIT_SUCCESS;
}