Displaying information from an external file in C - c

How do I read in an external file and then either print the whole text or selected lines?
FILE *fp;
fp=fopen("c:\\students.txt", "r");
I understand that reads the file but after that I am lost. Help please!!!
Do I need to read in binary or is text file acceptable?

You get a pointer to the file stream with fopen()
fread() will only return the amount of actual data that the program
could find inside your .txt file - It's very misleading. The main use is getting the number of elements for your loops. You can upload a file into your program, and print it on the screen without ever touching this function, if you know exactly what the file should already have. Only use this if you don't know what's in your file.
getline() is your go-to for printing out a specific line. No way around this one, and you'll need the specific library for it.
Here's an Example Code I wrote while doing a self-study on this, just showing how each of these are used, and printing out on BOTH the program, and a separate txt file outside the program. It doesn't have getline() however.
/*
Goals:
Create an array of 5 values
Input 5 vales from a pre-created file, into the new array
Print out the 5 values into another file.
Close the file.
*/
#include <stdio.h>
#include <stdlib.h>
#define DATAFILE "E:/Data.txt"
#define REPORT "E:/Report.txt"
//prototypes
FILE *Open_File();
void Consolodate_Array(int a_array[], FILE *file_pointer);
void Print_File(int a_array[], FILE *report_pointer);
void end_function(FILE *file_pointer, FILE *report_pointer);
int main(int argc, char *argv[])
{
int array[5];
FILE *Datatext = Open_File();
//Declared "Datatext" to be equal to Open_File's Return value.
//FILE itself is like Int, Double, Float, ect.
FILE *ReportText = fopen(REPORT, "w");
//Did the same as above, just not in a separate function. This gives us a
//Pointer to the REPORT.txt file, in write mode instead of read mode.
Consolodate_Array(array, Datatext);
Print_File(array, ReportText);
end_function(Datatext, ReportText);
system("PAUSE");
return 0;
}
/*----------------------------------------------------------------------*/
//This function should open the file and pass a pointer
FILE *Open_File()
{
return fopen(DATAFILE, "rb");
}
/*----------------------------------------------------------------------*/
//This function should input the variables gotten for the file, into the array
void Consolodate_Array(int a_array[], FILE *file_pointer)
{
for(int i=0; i<5; i++)
fscanf(file_pointer, "%i", &a_array[i]);
}
/*----------------------------------------------------------------------*/
//This function prints out the values into the second file, & at us too.
void Print_File(int a_array[], FILE *report_pointer)
{
for(int i=0; i<5; i++)
{
printf("%i\n", a_array[i]);
fprintf(report_pointer, "%i\n", a_array[i]);
}
}
/*----------------------------------------------------------------------*/
//This function closes the file.
void end_function(FILE *file_pointer, FILE *report_pointer)
{
fclose(file_pointer);
fclose(report_pointer);
//closes both files we worked on.
}

Related

fscanf not reading in file

I am trying to read in a file and it tells me it cant find the file. I built i have a built in checker that looks to see if the file is there. I have the data file in my debug folder. Am I reading the file incorrectly? I am also using codeblocks for the IDE.
Here is my function calling my file:
char fileData[3];
int bound = 96;
//file pointer and file info
FILE *ips;
ips = fopen("data.txt", "r");
if (ips == NULL)
printf("Please check file!\n"); //this is the output I get
else {
//for loop to scan through file, and retrive the letters
int i;
for(i=0; i<bound; i++)
fscanf(ips, "%c", &fileData);
addBoggleData(head1, fileData);
}
//closes the file system
close(ips);
}
you stated the file failed to open.
Since the fopen() file name parameter has no path info.
and you stated the file is in the debug directory.
1) the execution and the file must be in the same directory
2) in this case, both the executable and the data file must be in the debug directory.
You are passing the wrong parameter to fscanf(), you should pass the address of the ith element, like this
fscanf(ips, "%c", &fileData[i]);
and to be able to tell whether the data was read succesfully, you must check the return value of fscanf(), like
if (fscanf(ips, "%c", &fileData[i]) != 1)
{
warningReadingFailure();
}
Also, the fileData array is way too small, you need to make it at least as big, as the number of bytes you intend to read from the file, i.e.
int bound = 96;
char fileData[bound];

Processing each line to be stored as a structure

I am writing a program which should do multiple things including prompting the user for the name of the input file which I have done, but I am having troubling implementing a process where the program processes each line from a file, storing it as a struct data structure, finally using the malloc, calloc commands it will store all the valid records in memory to be validated. So any help on how to do this would be helpful.
#include <stdio.h> //library including standard input and output functions
#include <stdlib.h> //library including exit and system functions used below
#include <string.h> //library including string functions used
struct packet{
int source;
int destination;
int type; // Varibles for the structure
int port;
char data[50];
char * filename;
};
int main ()
{
printf("**************Details*******************************\n");
printf("*****Student name: ***********************\n");
printf("*****Course name: *******\n");
printf("*****Student ID: ************************ \n");
printf("\n");
// The program must prompt for the name of the input file. If it doesn't exist the program should stop with an error message
FILE *DataFile;
char filename[10] = { '\0' } ;
char DataLine[70];
printf("Enter the filename you wish to open\n");
scanf("%s", &filename);
if (( DataFile = fopen(filename, "r")) == NULL)
{
printf ("*****file could not be opened. : %s\n", filename);
exit(1);
}
// Read the data from this file
char *fgets(DataLine, 70, (FILE) *DataFile);
system("pause");
return 0;
}
Here is the text file the program should take the data from
0001:0002:0003:0021:CLS
0001:0010:0003:0021:CLS
0001:0002:0002:0080:<HTML>
0005:0002:0002:8080:<BR>
0005:0012:0002:8080:<BR>
0001:0002:0002:0080:<BODY>
0005:0002:0002:8080:<B>HELLO</B><BR>
0002:0004:0002:0090:100000000000000000022
0001:0002:0003:0021:DEL
0002:0004:0002:0010:100000000000000000023
Each colon from the file shows what part of the packet structure it should be a part of, i.e. the first set of 4 numbers is the "source" then "destination and so forth.
One way to do this is :
Use fgets to read the file line by line.
For each line, use strtok to tokenize the string.
For each of the first four tokens, use strtol to convert it to an integer.
A. The line char *fgets(DataLine, 70, (FILE) *DataFile); should probably just read fgets(DataLine, 70, DataFile);
B. If you create a single variable you don't really need malloc since the compiler will allocate it, but if you are planning on creating an array of Data you will only need to call malloc once to create the whole array, something like:
struct packet* packetarr = malloc(sizeof packetarr * DESIRED_ARRAY_SIZE);
C. As downHillFromHere suggested, use strtok to get each part of the string and strtol to convert the read strings to numbers when appropriate.

fwrite creates an output file that is bigger than the input file

I want to read a file bytewise into an array and then write the data of the array reversed
in a new file (program takes filename over command line argument). Tried it with an txt-file
and it worked, but if I try it on a jpg-file the new file is bigger than the original!
The determined file size saved in long size; is also correct for jpg-files and write loop
get size-time executed writing one char (char is one byte big, I am right?).
Does anybody know how the output file can get bigger than size*byte?
It doesn't seem logical to me!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char* argv[])
{
FILE *file;
char *buffer;
long size;
char filename[32];
if(argc>1)
{
//determine file size
file=fopen(argv[1],"r");
fseek(file,0,SEEK_END);
size=ftell(file);
rewind(file);
if(size>33554432) //32MB
{
fclose(file);
return 0;
}
//create buffer and read file content
buffer=malloc(33554432);
fread(buffer,1,size,file);
fclose(file);
//create new file name and write new file
strcpy(filename,argv[1]);
strcat(filename,"_");
file=fopen(filename,"w");
{
long i;
for(i=size-1;i>=0;i--)
{
fputc(buffer[i],file);
}
}
fclose(file);
free(buffer);
}
return 0;
}
The comments you're receiving are implying something: the newline character \n works differently in text mode on Windows compared with some other systems.
fputc('\n', file) on Windows actually writes two bytes if file was opened in text mode "w", as if you did fwrite("\r\n", 1, 2, file). This means for any \n byte read by fread, you're writing two bytes back.
If you want to write binary data back, you need to open your output file using the mode "wb" to fopen(). You also need to open it for reading in binary mode, "rb".

'fopen' in C can't open existing file in current directoy on Unix

I am using fopen(3) in C to read file and process it. The file is present in current working directory where the binary exists, but I am unable to read the file (Linux environment / Cygwin environment).
Here is the sample code:
C code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
FILE *inFile;
static char fileName[255];
int process_file(FILE *inFile)
{
char ch;
inFile = fopen(fileName,"r");
if (inFile == NULL)
{
perror(fileName);
exit(1);
}
else
{
// Process file
}
fclose(inFile);
return 0;
}
int main(int argc, char *argv[])
{
printf("Enter filename to process \n");
scanf("%s", fileName);
process_file(inFile);
getchar();
return 0;
}
I have file permissions set to 777 in the current directory. The resulting binary as well as my source code reside in this directory where the input file exits. Why is the file not opened?
Update :
This question was written in few years back and this code could be improved a lot.
1. The process file should accept char * or char array instead of file pointer
2. unused variables can be removed
3. unused libraries or include files can be removed
4. Can make use of argv to accept filename with path from cmdline
5. return instead of exit in process_file and also proper return code instead of returning 0 from process_file.
I should have asked this question little more elaborate...
I had three functions to process the same file, like process_fil1e1(), process_file2() and process_file3() even though I called fclose() in all three functions. Somehow the file handle was not closed that properly or the file pointer pointed to EOF or some undefined behavior. It was not working fine.
When I used a single process file and rewind() together, it worked fine...
Be sure to input file name with its extension. This may cause problems with reading the file.
If you know the extension of the file you can input only the name and after that make the program add the extension. After scanf("%s", fileName); add strcat(fileName, ".txt"); if you want to enter only the name without extension and the file you read has extension .txt.
Your inFile and fileName variables are extern so you don't need to have arguments for the function process_file();, any function can access those variables.
You can change function int process_file(); to void process_file(); and delete return 0, you don't need that.
You have declared the inFile and fileName as global. You should change your function prototype from
int process_file(FILE *inFile)
to
int process_file()
This would at least make your program more clear. Now regarding your problem: It would almost certain be that you are doing something wrong in the input file (like not putting in the file extension) in your input. Remember, you need to pass the complete file name (including the extension which on some systems like Windows (by default) would be hidden). Otherwise, the logic looks correct to me, and it should work fine.

file NULL not being forgotten by loop - C

I'm trying to check a directory for a file. I've done that properly. But I'm having trouble for exceptions--> when the file is not there. Here's what I am wanting to do: I 'd like to check for the file, if it exists, then exit the loop. If the file does not exist, then sleep. After sleeping for 3 seconds, check for the file again. Repeat until the file is found then return to main() and print "Hello everyone".
Currently, if the file is missing and i put the file into this directory while the program is running, it never recognizes the new file until i stop the program then start it back up. I want the program to check for the file again after sleep.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <unistd.h>
#define MYFILE "/Users/stackoverflow/Documents/fileabc123"
int checkfile() {
FILE *pFile;
pFile = fopen(MYFILE,"r");
char file_string[40];
int repeat = 0;
while( repeat < 1) {
if (pFile!=NULL) {
fgets (file_string,36,pFile);
fclose (pFile);
printf("%s\n", file_string);
repeat = 1 ;
}
if (pFile ==NULL) {
printf("Machine cannot read system file. \n");
sleep(3);
}
}
}
int main (int argc, char ** argv) {
checkfile();
printf("Hello everyone\n");
return 0;
}
You need to put the fopen in the loop.
if ((pFile = fopen(MYFILE, "r")) != NULL) {
// read it
}
else {
printf("Failed opening");
}
The error is in the loop.
you simply aren't trying to open the file again :)
this give you 2 error:
1. if you put the file it is not seen, as the program does not try to open it
2. if the file is present, you read it, then you close it, leaving an INVALID file descriptr but that is NOT null
this mean next loop you will try to read an invalid file descriptor. It is like reading/writing value with a overflow index from an array, or from a free() pointer.
You will almost always have the right value.. until that ram is reallocated.
so:
1. you have to try to open a file, until you get a valid file descriptor.
2. close will not change pointer value. It simply can't, think about it.
if you whant to change the value of somthing, you have to give it's address. A pointer is the adress of somthing. So File* is pointing to a File, but if you want to change the address pointed by File*, you need it's address (&pFile), just like a scanf :)

Resources