Cant write a 2d array on a FILE on C - arrays

char arrTypeLabels[3][7]= {{"Random"},{"ASC"},{"DESC"}};
FILE *f;
f= fopen( "TIMES.txt", "wb");
if (f == NULL)
{
printf("Error! Could not open file\n");
exit(-1);
}
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<7;j++)
{
printf("%c",arrTypeLabels[i][j]);
fwrite(arrTypeLabels[i][j],sizeof(char),sizeof(arrTypeLabels),f);
}
}
fclose(f);aenter code here
Im opening the TIMES.txt file but i cant see any output, althought i think my code is right .......................... :/ pls help...

char arrTypeLabels[3][7] = {
{"Random"},
{"ASC"},
{"DESC"}
};
FILE *f = fopen("TIMES.txt", "wb"); //wb is OK
if (f == NULL)
{
printf("Error! Could not open file\n");
exit(-1);
}
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 7; j++)
{
printf("%c", arrTypeLabels[i][j]);
fwrite(arrTypeLabels[i] + j, sizeof (char), sizeof (char), f); //your mistake is here
}
}
fclose(f);
I don't know how you're even able to copile your code, because in fwrite, the first argument needs to be a pointer, or in your code, you're giving the value.
Also, what you're trying to do is confusing, because it looks like you're trying to write char by char, but you're attempting to write the whole data contained in arrTypeLabels in one fwrite call.

If you just want to write that array to a file, you can make something like :
char arrTypeLabels[3][7]= {{"Random"},{"ASC"},{"DESC"}};
FILE *f;
f= fopen( "TIMES.txt", "wb");
if (f == NULL)
{
printf("Error! Could not open file\n");
exit(-1);
}
fwrite(arrTypeLabels,sizeof(char),sizeof(arrTypeLabels),f);
fclose(f);
or something like :
char arrTypeLabels[3][7]= {{"Random"},{"ASC"},{"DESC"}};
FILE *f;
f= fopen( "TIMES.txt", "wb");
if (f == NULL)
{
printf("Error! Could not open file\n");
exit(-1);
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 7; j++)
fwrite(arrTypeLabels[i] + j,sizeof(char),sizeof(char),f);
}
fclose(f);
note that the first method is much faster since you don't have to write (to a file i.e into the hard drive) every single character one at a time.

fwrite first and third parameters are wrong. Since you want to write char by char, your line should be fwrite(&buf[i][j], 1,1,f);
Or simplier, use fputc:
fputc(buf[i][j], f);

Related

Save/Load function in C language

I am working on a game program that requires me to save a 2D array into a file, and then if the user wants to go back to that game then can load it back up and continue it. But I am having a problem with getting the array to save into a txt file. And for the load function, it is not being able to load anything. The user is supposed to select the load option and it should be able to call the txt file with the array and then allows them to continue playing the game.
This is my save function
void save(char *filename)
{
FILE *fp = fopen(filename, "wb");
fwrite(&size, sizeof(size), 1 , fp);
fwrite(board, sizeof(int), size, fp);
if(fp == NULL)
return;
fclose(fp);
}
This is my load function
void load(char *filename)
{
FILE *fp = fopen(filename, "rb");
fread(&size, sizeof(size), 1 , fp);
fread(board, sizeof(int), size, fp);
if(fp == NULL)
return;
fclose(fp);
}
Later in the code, I use a menu to call these functions.
Any help would be very appreciated!
board is not a 2D array, it's an array of pointers to rows. You need to loop over it, writing and reading each row separately.
Since the size of the board being loaded may be different from the board currently in memory, you need to free the old board and re-allocate the new one when loading.
void save(char *filename)
{
FILE *fp = fopen(filename, "wb");
if (!fp) {
perror("Can't open save file");
return;
}
fwrite(&size, sizeof(size), 1 , fp);
for (int i = 0; i < size; i++) {
fwrite(board[i], sizeof(*board[i]), size, fp);
}
fclose(fp);
}
void load(char *filename)
{
FILE *fp = fopen(filename, "r");
if (!fp) {
perror("Can't open save file");
return;
}
if (board) {
for (int i = 0; i < size; i++) {
free(board[i]);
}
free(board);
}
fread(&size, sizeof(size), 1 , fp);
board = malloc(size * sizeof(*board));
for (int i = 0; i < size; i++) {
board[i] = malloc(size * sizeof(*board[i]));
fread(board[i], sizeof(*board[i]), size, fp);
}
fclose(fp);
}
First of all, write RB while loading. Second, don't forget to close all of the files after entering the FILE command.
Additionally, I have advice for you: Always check if *fp is equal to NULL; it's great for debugging and can have huge impact on your code. You can also write a function for multiple checking while using file in your program.

Writing to/reading from file using pointers, C

I've written a program to mess around with writing pointers into files(fwrite) and reading into pointers from files(fread). However the program doesn't seem to write a single thing into the file, nor does it seem to read anything from the file; it just prints the final incrementation of my pointer 5 times and exits. Can anyone spot the error/mistake in my syntax that seems to be doing this?
#include <stdio.h>
int main() {
FILE *fTest;
int *testPtr;
int x = 10;
if ((fTest = fopen("test.c", "wb")) == NULL) {
printf("Error!");
}
testPtr = &x;
int i;
for (i = 0; i < 5; i++) {
fwrite(testPtr, sizeof(int), 1, fTest);
*testPtr += 1;
}
for (i = 0; i < 5; i++) {
fread(testPtr, sizeof(int), 1, fTest);
printf("%d", *testPtr);
}
fclose(fTest);
}
Steps to take:
Write the data to the file.
Close the file.
Open the file again in read mode.
Read the data from the file.
That should work.
Also, the output file name, test.c, seems a bit strange. Is that on purpose?
#include <stdio.h>
int main() {
FILE *fTest;
int *testPtr;
int x = 10;
char const* file = "test.data"; // Using .data instead of .c
testPtr = &x;
int i;
// Write the data.
if ((fTest = fopen(file, "wb")) == NULL) {
printf("Error!");
}
for (i = 0; i < 5; i++) {
fwrite(testPtr, sizeof(int), 1, fTest);
*testPtr += 1;
}
fclose(fTest);
// Read the data.
if ((fTest = fopen(file, "rb")) == NULL) {
printf("Error!");
}
for (i = 0; i < 5; i++) {
fread(testPtr, sizeof(int), 1, fTest);
printf("%d", *testPtr);
}
fclose(fTest);
}
Left aside the fact that you don't check thre return value of fwrite() I would assume that you do write into "test.c", after you run the program the file should exist with a size of 5 * sizeof(int) bytes. But you can't read from it for two reasons:
you open the file write-only. Change "wb" to "w+b" to allow reading
after writing, you must reset the read-write pointer to the beginning of the file: call fseek(fTest, 0, SEEK_SET ); before reading
The problem is that you're reading from the file while it's opened in write mode.
Add this code between your write loop and read loop and it will work:
fclose(fTest);
if ((fTest = fopen("test.c", "rb")) == NULL) {
printf("Error!");
}

Read a file containing an array of long in C

I am trying to get the data from an array of longs that I have just created but I got different data.
please see code below :
#include <string.h>
#include "readfile.h"
int main()
{
long wr_data [6] ;
wr_data[0] = 11;
wr_data[1] = 1100;
wr_data[2] = 1122323;
wr_data[3] = 11333;
wr_data[4] = 11434243;
wr_data[5] = 1166587;
writeFile(wr_data);
readFile();
return(0);
}
int readFile()
{
FILE *file;
long * data
printf("Error Reading File\n");;
/* Open file for both reading and writing */
file = fopen(fileName, "r");
if (file == NULL)
{
printf("Error Reading File\n");
return -1;
}
for (int i = 0; i < 5; i++)
{
fscanf(file, "%ld", &data[i] );
printf("data[%d]: %ld \n",i, data[i]);
}
fclose(file);
return 0;
}
int writeFile(long * data)
{
FILE *fp;
if (data != NULL)
{
if ((fp = fopen(fileName,"w")) == NULL)
return -1;
if (*data !=0 )
fwrite(data,sizeof(long),6,fp);
printf("Write data\n");
fclose(fp);
}
return 0;
}
the result I get is as follows :
Write data
data[0]: 140526045102081
data[1]: 47
data[2]: 197764
data[3]: 140526045102080
data[4]: 4096
I want to preserve the write function as it is as it comes from an existing code. I tried also the function fread but without success
fread(data, sizeof(long ), 6, file);
Thanks in advance for help.
It's working here. I made the following changes to your code:
//needed for malloc
#include <stdio.h>
//needed for output
#include <stdlib.h>
...
char *fileName = "so";
...
//allocate memory to store the values
long *data = (long *)malloc(sizeof(long)*6);
...
//read the stored longs
fread(data, sizeof(long ), 6, file);
int i;
for(i=0; i<6; i++)
printf("%ld\n", data[i]);
what do you think?
edit:
Well the main change was the memory allocation. When you want to store values of any kind, your program needs to be granted by the operating system a memory zone to store those values.
In this case we had two options, either create a staticly allocated array with a fixed size, or allocate the needed memory in a dynamic fashion with the malloc function or equivalent.
Don't forget, if you want to store something, first make sure you have a place for it to be stored (i.e. allocated memory). If you don't you will most likely get an error "Segmentation Fault" aka "SIGSEGV" which means that you tried to access memory that didn't belong to you.
Also, the "fscanf(file, "%ld", &data[i] );" will read "file" as text and will try to parse floats out of that same text. Since you're storing the longs as longs and not as text, this will not work, since you're writing and reading different things.
You are writing the binary content of the array to the file and afterwards try to interpret this as a long value which can obviously not work. If you want to store the numbers as text you must convert them to text before writing or print them to file by using the fprintf(FILE *, const char *, ...) function.
It is working as expected using the following code using a text file (you might want to change the filename). Otherwise you could just fwrite and fread the whole content, depending on your needs.
#include <stdio.h>
const char *filename = "yourfile";
int readFile()
{
FILE *file;
long data[6];
int i;
printf("Error Reading File\n");;
/* Open file for both reading and writing */
file = fopen(filename, "r");
if (file == NULL)
{
printf("Error Reading File\n");
return -1;
}
for (i = 0; i < 6; i++)
{
fscanf(file, "%ld", &data[i] );
printf("data[%d]: %ld \n",i, data[i]);
}
fclose(file);
return 0;
}
int writeFile(long * data)
{
FILE *fp;
int i;
if (data != NULL)
{
if ((fp = fopen(filename,"w")) == NULL)
return -1;
if (*data !=0 )
{
for(i = 0; i != 6; ++i)
fprintf(fp, "%ld ", data[i]);
}
printf("Write data\n");
fclose(fp);
}
return 0;
}
int main()
{
long wr_data [6] ;
wr_data[0] = 11;
wr_data[1] = 1100;
wr_data[2] = 1122323;
wr_data[3] = 11333;
wr_data[4] = 11434243;
wr_data[5] = 1166587;
writeFile(wr_data);
readFile();
return(0);
}

FILE pointer is expired without rhyme or reason

I have this problem after I add some socket connection codes after following codes. What could be a reason when fp is ok, pointing some memory address, while reading the data (line 4), but when debugger(gdb) reaches the if block, fp pointer is just pointing 0x0.
#define CHANNELS_PER_IOM 25
...
int OldValues[CHANNELS_PER_IOM];
FILE * fp;
FILE * fp_t;
int buff;
int i;
fp = fopen("/windcom/tmp/dout_values", "r");
fp_t = fopen("/windcom/tmp/dout_values.tmp", "w");
i = 0;
while(fp && fscanf(fp, "%d\n", &buff) == 1) // fp is pointing some address here.
{
i++;
OldValues[i-1] = buff;
//printf("%d %d \n", OldValues[i-1], buff);
}
if(!fp) //fp is pointing 0x0 here.
{
for(i=0; i<CHANNELS_PER_IOM; i++)
{
OldValues[i] = 0;
}
}
Where is OldValues defined? You have probably not large enough and unfortunately the fp is getting overwritten inadvertently.
EDIT
Try this code:
while(i < CHANNELS_PER_IOM &&
fp &&
fscanf(fp, "%d\n", &OldValues[i++]) == 1) // fp is pointing some address here.
{
// Empty
}
EDIT 2
Put
And after
fp = fopen("/windcom/tmp/dout_values", "r");
put
if (!fp) printf("Unable to open file\n");
and this will check if the file is actually opened.

Cant seem to get fgetc working the second time reading a file

I'm reopening and reading a file, SORTED.txt, after closing it from its first time use - copying all the contents of another file, UNSORTED.txt.
After copying from UNSORTED.txt, I wanted to count the number of lines of what I've copied (as a seperate process, and not during the copy process). It seems that fegtc() does not point at the beginning of the file (SORTED.txt) the second time over, hence the value of lines remains as what it was initialized as, 0. Also, in general, can I get the repointing of fgetc() done without closing and reopening the file in consideration?
Grateful for any help.
Cheers!
f = fopen("./TEXTFILES/UNSORTED.txt", "w");
if (f == NULL){
printf("ERROR opening file\n");
return 100;
}
for (i=0; i<1000000; i++){
fprintf(f, "%d\n", (23*rand()-rand()/13));
}
fclose(f);
f = fopen("./TEXTFILES/UNSORTED.txt", "r");
if (f == NULL){
return 100;
}
s = fopen("./TEXTFILES/SORTED.txt", "w");
if (s == NULL){
return 101;
}
while(1){
j = getc(f);
if (j == EOF) break;
fputc(j, s);
}
fclose(f);
//Closed source file. Read number of lines in target file.
fclose(s);
s = fopen("./TEXTFILES/SORTED.txt", "w");
j = 0;
while(1){
j = fgetc(s);
if (j == EOF) break;
if (j == '\n') lines++;
}
fclose(s);
printf("\n%d\n", lines);
You are opening the file in "w" (write) mode:
s = fopen("./TEXTFILES/SORTED.txt", "w");
but reading from it:
j = fgetc(s);
You probably meant to open it in read mode:
s = fopen("./TEXTFILES/SORTED.txt", "r");
^^^
It sounds like you've got it figured out! But since I went through the effort of putting this example together, I thought I'd post it anyways.
#include <stdio.h>
int main()
{
FILE * f;
FILE * s;
int i, j;
int lines = 0;
f = fopen("./TEXTFILES/UNSORTED.txt", "w+");
if (f == NULL){
printf("ERROR opening file\n");
return 100;
}
for (i=0; i<1000000; i++){
fprintf(f, "%d\n", (23*rand()-rand()/13));
}
s = fopen("./TEXTFILES/SORTED.txt", "w+");
if (s == NULL){
fclose(f); // cleanup and close UNSORTED.txt
return 101;
}
// rewind UNSORTED.txt here for reading back
rewind( f );
while(1){
j = getc(f);
if (j == EOF) break;
fputc(j, s);
}
// done with UNSORTED.txt. Close it.
fclose(f);
// rewind SORTED.txt here for reading back
rewind( s );
j = 0;
while(1){
j = fgetc(s);
if (j == EOF) break;
if (j == '\n') lines++;
}
fclose(s);
printf("\n%d\n", lines);
return 0;
}

Resources