Writing to/reading from file using pointers, C - 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!");
}

Related

Cant write a 2d array on a FILE on C

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);

C project with files

I need some help with my C project:
I need to write a c program who receives 2 parameters:
1) The name of a text file(infile) which is in the same catalog
2) A number k>0
And creates 2 new files,outfile1 & outfile 2 as:
Outfile 1: k,2*k,3*k…. character of infile
Outfile 2: k,2*k,3*k…..line of infile
Example:
INFILE
Abcdefg
123456
XXXXXX
01010101
OUTFILE 1:
Cf25XX101
OUTFILE 2:
XXXXXX
I wrote some code ,but its not working. Any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** read_lines(FILE* txt, int* count) {
char** array = NULL;
int i;
char line[100];
int line_count;
int line_length;
*count = 0;
line_count = 0;
while (fgets(line, sizeof(line), txt) != NULL) {
line_count++;
}
rewind(txt);
array = malloc(line_count * sizeof(char *));
if (array == NULL) {
return NULL;
}
for (i = 0; i < line_count; i++) {
fgets(line, sizeof(line), txt);
line_length = strlen(line);
line[line_length - 1] = '\0';
line_length--;
array[i] = malloc(line_length + 1);
strcpy(array[i], line);
}
*count = line_count;
return array;
}
int main(int argc, char * argv[]) {
char** array = NULL;
FILE* file = NULL;
const char* filename = NULL;
int i;
int line_count;
int k;
char c;
printf("ENTER ONE PHYSICAL NUMBER\n");
do{
if(k>0)
scanf("%d",&k);
else{
printf("ENTER ONE PHYSICAL NUMBER\n");
scanf("%d",&k);
}
}while(k<=0);
file = fopen("LEIT.txt", "rt");
if (file == NULL) {
printf("CANT OPEN FILE %s.\n", filename);
return 1;
}
array = read_lines(file, &line_count);
printf("ARRAY:\n");
for (i = 0; i < line_count; i++) {
printf("[%d]: %s\n", (i+1), array[i]);
}
printf("CALCULATING OUTFILE1 AND OUTFILE2\n");
printf("OUTFILE1:\n");
for(i=0;i<line_count;i++){
c=i*k;
printf("%c\n",array[c]);
}
printf("WRITING OUTFILE1 COMPLETE!\n");
printf("OUTFILE2:\n");
for(i=0;i<line_count;i++){
c=i*k;
printf("%c\n",array[c]);
}
printf("WRITING OUTFILE2 COMPLETE!\n");
return 0;
}
My actual problem is calculate and write into files (outfile1 and outfile2) the result...
You need to close file after finishing reading/writing it with fclose.
You can create and write strings to a file using fopen with correct mode.
You can output formatted string to a file by using fprintf.
It seems that you don't want to print the 0th character/line, so in the last for loop, i should start from 1 (or start from 0 but add 1 later).
array[c] is a string, not a character. So when printing it, you should use %s specifier instead of %c.
It is not a good idea using char as count in later for loops unless you know input file will be very short. signed char can only count to 127 before overflow (unsigned char can count to 255). But if you have a very long file, for example thousands of lines, this program would not work properly.
array is malloced in function char** read_lines(FILE* txt, int* count). After finish using it, you need to dealloc, or free it by calling
for (i = 0; i < line_count; i++) {
free(array[i]);
}
and followed by free(array). This avoids memory leakage.
Modified code is here. In the following code, char c is not used. This is the part where you process output files, and before return 0; in main function.
printf("CALCULATING OUTFILE1 AND OUTFILE2\n");
printf("OUTFILE1:\n");
// Since we finished using LEIT.txt, close it here.
fclose(file);
// Mode: "w" - Write file. "+" - Create if not exist.
// You can lso use "a+" (append file) here if previous record need to be preserved.
FILE *out1 = fopen("OUTFILE1.txt", "w+");
FILE *out2 = fopen("OUTFILE2.txt", "w+");
if ((out1 == NULL) || (out2 == NULL)) {
printf("CANT CREATE OUTPUT FILES.\n");
return 1;
}
// Out file 1.
unsigned int count = k;
for (i = 0; i < line_count; i++){
while (count < strlen(array[i])) {
// This just prints to stdout, but is good for debug.
printf("%c", array[i][count]);
// Write to the file.
fprintf(out1, "%c", array[i][count]);
// Calculate c for next char.
count += k + 1;
}
// Before go to next line, minus string length of current line.
count -= strlen(array[i]);
}
printf("\n");
printf("WRITING OUTFILE1 COMPLETE!\n");
// Close file.
fclose(out1);
// Out file 2.
printf("OUTFILE2:\n");
for (i = 1;i < line_count / k; i++){
count = i * k;
// This just prints to stdout, but is good for debug.
printf("%s\n", array[count]);
// Write to the file.
fprintf(out2, "%s\n", array[count]);
}
printf("WRITING OUTFILE2 COMPLETE!\n");
//Close file.
fclose(out2);
// dealloc malloced memory.
for (i = 0; i < line_count; i++) {
free(array[i]);
}
free(array);

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);
}

Run-time Error for a C program

I found this program on the internet so I decided to try it, it converts a file to another type of file. I compiled and ran on my MAC OS X 10.9.1 through terminal, but it gave me a segmentation fault 11. What can I do to fix this?
#include <stdio.h>
#define SRAM_SIZE (32 * 1024)
typedef FILE* pfile;
static unsigned char SRAM[SRAM_SIZE];
int main(void)
{
pfile in, out;
register int i;
in = fopen("input.sra", "rb");
for (i = 0; i < SRAM_SIZE; i++)
SRAM[i ^ ~0&3] = fgetc(in);
fclose(in);
out = fopen("output.sra", "wb");
for (i = 0; i < SRAM_SIZE; i++)
fputc(SRAM[i], out);
fclose(out);
return 0;
}
You have no error checking. Change:
in = fopen("input.sra", "rb");
for (i = 0; i < SRAM_SIZE; i++)
SRAM[i ^ ~0&3] = fgetc(in);
fclose(in);
...
to:
in = fopen("input.sra", "rb");
if (in == NULL)
{
printf("Unable to open 'input.sra'.\n");
return -1;
}
for (i = 0; i < SRAM_SIZE; i++)
SRAM[i ^ ~0&3] = fgetc(in);
fclose(in);
...
You should do the same for the output file too. There are a lot of ways this can fail and just blindly accessing an untested value is bad practice.

How to create char[][] from txt file in C?

I am pretty new to C and I have got a problem here in C:
I want to write a program which reads a txt file and writes the content it a char[50][50].
To read the file I used fopen but I have no idea how to write this into the array. What is a good way to solve this?
Easy to use fread if it only read from a file the size of the specific.
E.g.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
char data[50][50];
int count;
if(NULL==(fp=fopen("data.txt","r"))){
perror("file not open\n");
exit(EXIT_FAILURE);
}
count=fread(&data[0][0], sizeof(char), 50*50, fp);
fclose(fp);
{ //input check
int i;
char *p = &data[0][0];
for(i=0;i<count;++i)
putchar(*p++);
}
return 0;
}
EDIT: #BLUEPIXY's answer is significantly better than this approach.
#Hidde's code adapted for this specific example:
// Include the standard input / output files.
// We'll need these for opening our file
#include <stdio.h>
int main ()
{
// A pointer to point to the memory containing the file data:
FILE * pFile;
// Open the file itself:
pFile=fopen ("250.txt","r");
// Check that we opened the file successfully:
if (pFile==NULL)
{
perror ("Error opening file");
}
else
{
// The file is open so we can read its contents.
// Lets just assume its got 50*50=250 chars in.
// Initialise an array to hold our results:
char array[50][50];
int row, col;
for (row = 0; row < 50; row++)
{
for (col = 0; col < 50; col++)
{
// Store the next char from our file in our array:
array[row][col] = fgetc (pFile);
}
}
// Close the file
fclose (pFile);
// Demonstrate that we've succeeded:
for (row = 0; row < 50; row++)
{
for (col = 0; col < 50; col++)
{
printf("%c", array[row][col]);
}
printf("\n");
}
}
// Return 0 indictaes success
return 0;
}
Really there should be some code to check that the input file meets your expectations, otherwise strange things may happen.
/* fgetc example: money counter */
#include <stdio.h>
int main ()
{
FILE * pFile;
int c;
int n = 0;
pFile=fopen ("myfile.txt","r");
if (pFile==NULL) perror ("Error opening file");
else
{
do {
c = fgetc (pFile);
if (c == '$') n++;
} while (c != EOF);
fclose (pFile);
printf ("The file contains %d dollar sign characters ($).\n",n);
}
return 0;
}
Copied from CPlusPlus.com. You can read the file using fgetc(FILE* ). You make a while loop, in which you test if the last character read is not the end of the file. I hope you can fill your array with this code.

Resources