Trouble reading and writing to files in C - c

I have written the following code (as part of ab assignment for university) in an attempt to save 1 int to a text file (using fprintf) and an array of structs of type Flight to a .bin file. It seems that both are remaining empty. I am calling the read at the beginning of the program and the write on exit or when the Save option is selected. The read must first take the int value as it is a crucial counter for how many elements there are (and therefore how many need to be read / written).
I have looked at other answers, and even based some of my code off them however after reading and re-reading I still could not find a solution hence i posted a new question.
This is the Write Section, The files are flyC.txt (to store the counter) and fly.bin to store the array of structs.
void writeFlight (){
FILE * cpt;
if ((cpt = fopen("flyC.txt", "wb")) == NULL)
{
printf("ERROR: Flight Count File Could Not Be Opened / Written To \n");
}
fprintf(cpt, "%d", curFly);
FILE * fpt;
if ((fpt = fopen("fly.bin", "wb")) == NULL)
{
printf("ERROR: Flight File Could Not Be Opened / Written To \n");
}
fwrite(flyList, curFly * sizeof(struct Flight), 1, fpt);
fclose(fpt);
}
And here is the Read section.
void readFlight(){
//First Read file with variable curFly
FILE * cpt;
if((cpt = fopen("flyC.txt", "rb")) == NULL)
{
printf("ERROR: Flight Count File Could Not Be Opened\n");
}
if (1 != fscanf(cpt, "%d", &curFly)){
printf("ERROR: Flight Count File Could Not Be Read\n");
}
fclose(cpt);
FILE * fpt;
if((fpt = fopen("fly.bin", "rb")) == NULL)
{
printf("ERROR: Flight File Could Not Be Opened / Read\n");
}
fread(flyList, sizeof(struct Flight) * curFly, 1, fpt);
fclose(fpt);
}
Any help is appreciated!

I see several issues here.
I understood that flyC.txt was supposed to contain plain ASCII text rather than binary data. If this is the case, than you shouldn't use "wb" when opening cpt for writing, but just "w"
While writing cpt you don't close it. The OS might close it for you at the end of the program, but you shouldn't rely on this.
While reading the file back, you've done a similar mistake for flyC.txt; you shouldn't open it using “rb" but just "r" if it contained binary data.

You forgot fclose(cpt); in the write function.
Also you should return on error and not call fread/fwrite.

Related

How to read a file and compare values in C?

I need to know how could I read a file with values in different lines, and compare it with values I have in memory, to get wich line has a better score, and if values in memory are best, insert those values into the file (the file is open as read and as write at the same time, as this part of code could be run from several fork() at the same time):
if (PuntuacioEquip(jugadors)>MaxPuntuacio && CostEquip(jugadors)<PresupostFitxatges)
{
//Compare with file
int fd, n;
TBestEquip info;
fd = open("best_teams.txt", O_RDONLY);
if (fd<0) panic("open");
while ((n=read(fd, &info, sizeof(info))) == sizeof(info)) {
//printf(cad,"equip %lld, puntuacio %d\n", info.Equip, info.Puntuacio);
//write(1,cad,strlen(cad));
if (info.Puntuacio>PuntuacioEquip(jugadors))
{
fd = open("best_teams.txt", O_WRDONLY|O_TRUNC|O_CREAT,0600);
if (fd<0) panic("open");
sprintf(cad,"%s Cost: %d Points: %d. %s\n", CostEquip(jugadors), PuntuacioEquip(jugadors));
write(fd,cad,strlen(cad));
}
}
// We have a new partial optimal team.
MaxPuntuacio=PuntuacioEquip(jugadors);
memcpy(MillorEquip,&jugadors,sizeof(TJugadorsEquip));
sprintf(cad,"%s Cost: %d Points: %d. %s\n", color_green, CostEquip(jugadors), PuntuacioEquip(jugadors), end_color);
write(1,cad,strlen(cad));
}
Appreciate any help.
Regards,
The best way to iterate through a file is to use the function getline(). Here is an example of its utilisation, taken from this post which I advise you read.
char const* const fileName = "best_teams.txt" ; //
FILE* file = fopen(fileName, "r"); /* should check the result */
if (file != NULL) {
char line[256];
while (getline(line, sizeof(line), file)) { // Each iteration, a line will be stored in string `line`
// Do what you want to do
} // Exits when arrives at the end of the file
else puts("Error while opening file\n");
As suggested in the comments, you can then use fopen("best_teams.txt", "w")
The "w" means write mode, which is described as follow in fopen documentation :
Creates an empty file for writing. If a file with the same name already exists, its content is erased and the file is considered as a new empty file.
Another solution is to open in read and write mode, and to only change the values you desire, but it might be more complicated.

fscanf while-loop never runs

I'm working on a project, and I can't seem to figure out why a piece of my function for finding prime numbers won't run. Essentially, I want to code to first check the text file log for any previously encountered prime numbers, but no matter what I put for the while-loop containing fscanf(), it seems like my code never enters it.
int filePrime(int a) {
int hold = 0;
FILE *fp = fopen("primes.txt", "a+");
if (fp == NULL) {
printf("Error while opening file.");
exit(2);
}
/*
the while loop below this block is the one with the issue.
on first run, it should skip this loop entirely, and proceed
to finding prime numbers the old-fashioned way, while populating the file.
instead, it is skipping this loop and proceeding right into generating a
new set of prime numbers and writing them to the file, even if the previous
numbers are already in the file
*/
while (fscanf(fp, "%d", &hold) == 1){
printf("Inside scan loop.");
if (hold >= a) {
fclose(fp);
return 1;
}
if (a % hold == 0) {
fclose(fp);
return 0;
}
}
printf("Between scan and print.\n");
for (; hold <= a; hold++) {
if (isPrime(hold) == 1) {
printf("Printing %d to file\n", hold);
fprintf(fp, "%d\n", hold);
if (hold == a)
return 1;
}
}
fclose(fp);
return 0;
}
I have tried all sorts of changes to the while-loop test.
Ex. != 0, != EOF, cutting off the == 1 entirely.
I just can't seem to get my code to enter the loop using fscanf.
Any help is very much appreciated, thank you so much for your time.
In a comment, I asked where the "a+" mode leaves the current position?
On Mac OS X 10.11.4, using "a+" mode opens the file and positions the read/write position at the end of file.
Demo code (aplus.c):
#include <stdio.h>
int main(void)
{
const char source[] = "aplus.c";
FILE *fp = fopen(source, "a+");
if (fp == NULL)
{
fprintf(stderr, "Failed to open file %s\n", source);
}
else
{
int n;
char buffer[128];
fseek(fp, 0L, SEEK_SET);
while ((n = fscanf(fp, "%127s", buffer)) == 1)
printf("[%s]\n", buffer);
printf("n = %d\n", n);
fclose(fp);
}
return(0);
}
Without the fseek(), the return value from n is -1 (EOF) immediately.
With the fseek(), the data (source code) can be read.
One thing slightly puzzles me: I can't find information in the POSIX fopen() specification (or in the C standard) which mentions the read/write position after opening a file with "a+" mode. It's clear that write operations will always be at the end, regardless of intervening uses of fseek().
POSIX stipulates that the call to open() shall use O_RDWR|O_CREAT|O_APPEND for "a+", and open() specifies:
The file offset used to mark the current position within the file shall be set to the beginning of the file.
However, as chux notes (thanks!), the C standard explicitly says:
Annex J Portability issues
J.3 Implementation-defined behaviour
J.3.12 Library functions
…
Whether the file position indicator of an append-mode stream is initially positioned at
the beginning or end of the file (7.21.3).
…
So the behaviour seen is permissible in the C standard.
The manual page on Mac OS X for fopen() says:
"a+" — Open for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the then current end of file, irrespective of any intervening fseek(3) or similar.
This is allowed by Standard C; it isn't clear it is fully POSIX-compliant.

Trouble testing copy file function in C

Okay so this is probably has an easy solution, but after a bit of searching and testing I remain confused.. :(
Here is a snippet of the code that I have written:
int main(int argc, char *argv[]){
int test;
test = copyTheFile("test.txt", "testdir");
if(test == 1)
printf("something went wrong");
if(test == 0)
printf("copydone");
return 0;
}
int copyTheFile(char *sourcePath, char *destinationPath){
FILE *fin = fopen(sourcePath, "r");
FILE *fout = fopen(destinationPath, "w");
if(fin != NULL && fout != NULL){
char buffer[10000];//change to real size using stat()
size_t read, write;
while((read = fread(buffer, 1, sizeof(buffer), fin)) > 0){
write = fwrite(buffer, 1, read, fout);
if(write != read)
return 1;
}//end of while
}// end of if
else{
printf("Something wrong getting the file\n");
return 0;}
if(fin != NULL)
fclose(fin);
if(fout != NULL)
fclose(fout);
return 0;
}
Some quick notes: I am very new to C, programming, and especially file I/O. I looked up the man pages of fopen, fread, and fwrite. After looking at some example code I came up with this. I was trying to just copy a simple text file, and then place it in the destination folder specified by destinationPath.
The folder I want to place the text file into is called testdir, and the file I want to copy is called test.txt.
The arguments I have attempted to use in the copyFile function are:
"test.txt" "testdir"
".../Desktop/project/test.txt" ".../Desktop/project/testdir"
"/Desktop/project/test.txt" "/Desktop/project/testdir"
I just get the print statement "Something wrong getting the file" with every attempt. I am thinking that it may be because 'testdir' is a folder not a file, but then how would I copy to a folder?
Sorry if this a really basic question, I am just having trouble so any advice would be awesome!
Also, if you wanted to be extra helpful, the "copyTheFile" function is supposed to copy the file regardless of format. So like if its a .jpg or something it should copy it. Let me know if any of you guys see a problem with it.
This is with ISO/POSIX/C89/C99 on Linux.
At the start, you'll want to include stdio.h to provide FILE and the I/O function declarations:
#include <stdio.h>
Aside from this, your program compiles and works properly for me. Unfortunately you can't copy to a directory without using stat() to detect if the destination is a directory, and if so, appending a file name before opening the file.
Some other minor suggestions:
A buffer with a power of two bytes such as 4096 is probably more efficient due to it lining up with filesystem and disk access patterns
Conventionally, C functions that return a status code use 0 for success and other values such as 1 for failure, so swapping your return values may be less confusing
When a standard library function such as fopen, fread or fwrite fails, it is a good idea to use perror(NULL); or perror("error prefix"); to report it, which may look something like:
$ ./a.out
...
error prefix: No such file or directory
if you are trying to write a new file in a directory, you should be giving the full path of the file to be written. in your case
"C:...\Desktop\project\testdir\testfile"

How to write an array to file in C

I have a 2 dimensional matrix:
char clientdata[12][128];
What is the best way to write the contents to a file? I need to constantly update this text file so on every write the previous data in the file is cleared.
Since the size of the data is fixed, one simple way of writing this entire array into a file is using the binary writing mode:
FILE *f = fopen("client.data", "wb");
fwrite(clientdata, sizeof(char), sizeof(clientdata), f);
fclose(f);
This writes out the whole 2D array at once, writing over the content of the file that has been there previously.
I would rather add a test to make it robust !
The fclose() is done in either cases otherwise the file system will free the file descriptor
int written = 0;
FILE *f = fopen("client.data", "wb");
written = fwrite(clientdata, sizeof(char), sizeof(clientdata), f);
if (written == 0) {
printf("Error during writing to file !");
}
fclose(f);
How incredibly simple this issue turned out to be...
The example given above handle characters, this is how to handle an array of integers...
/* define array, counter, and file name, and open the file */
int unsigned n, prime[1000000];
FILE *fp;
fp=fopen("/Users/Robert/Prime/Data100","w");
prime[0] = 1; /* fist prime is One, a given, so set it */
/* do Prime calculation here and store each new prime found in the array */
prime[pn] = n;
/* when search for primes is complete write the entire array to file */
fwrite(prime,sizeof(prime),1,fp); /* Write to File */
/* To verify data has been properly written to file... */
fread(prime,sizeof(prime),1,fp); /* read the entire file into the array */
printf("Prime extracted from file Data100: %10d \n",prime[78485]); /* verify data written */
/* in this example, the 78,485th prime found, value 999,773. */
For anyone else looking for guidance on C programming, this site is excellent...
Refer: [https://overiq.com/c-programming/101/fwrite-function-in-c/

Reading in .txt file with different extension in C

At the moment my program has no problem reading in a .txt file, but my program needs to read in a text file with a different file extension (.emu is the requirement). When simply changing the same file's extension to .emu, the variable 'file' is NULL and therefore the file isn't opened, can anyone help?
Had a little look around and haven't been able to find a solution so any help is much appreciated
here's the source code:
void handleArgs (const char *filename, int trace, int before, int after) {
FILE *file = fopen(filename, "r");
char *address = malloc(MAX_ADD_LENGTH * sizeof(char));
char *instruction = malloc(MAX_INS_LENGTH * sizeof(char));
long int addressDecoded;
if (file == NULL || file == 0) {
fprintf(stderr, "Error: Could not open file");
}
else {
if (ferror(file) == 0) {
while (fscanf(file, "%s %s", address, instruction) != EOF) {
if (strlen(address) == 8 && strlen(instruction) == 8) {
addressDecoded = strtol(address, NULL, 16);
printf("%ld\n", addressDecoded);
//instruction = decodeInstruction(instruction);
}
else {
fprintf(stderr, "Error: particular line is of wrong length");
}
}
}
}
fclose(file);
}
argument 'filename' when executing is simply '/foopath/test.emu'
There's nothing special to C about the file extension. Reread your code for simple errors like changing the filename in one place, but not the other. If you're passing in the filename, pass the whole name, not just the part to the left of the period.
Files are data, and have names. What comes before the dot in a name, is just as much a part of it as what comes after -- the extensions were created just as hints as to what the file contains, but they are NOT required to be strictly related to the file's contents.
The file may not exist, or your priviledges may not be enough to open it. Or maybe there's some other kind of error. How can you diagnose this?
When you use a system call and it doesn't behave the way you want to, there's a variable called errno in errno.h (#include <errno.h>) that will contain a number representing the status of the last call. There's a huge list of symbolic constants to put names to these values, you can google it up.
For example, if you try to open a file and the returned pointer is useless, you might want to check errno to see if the file existed, or if you're exceding system restrictions for opened files, etc.

Resources