This question already has an answer here:
Garbage Value in File after write
(1 answer)
Closed 5 years ago.
i am trying to copy to a file the contents of two input files in c with the help of read, write and open. At first i tried to simply copy the contents of only one file that contains the 'hello' world, but this is what gets written:
"hello
h«Ú^?^#^#^A^#^#^#^#^#^#^#m G«Ú^?^#^#^#^#^#^#^#^#^#^#^Pjh«Ú^?^#^#^A^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^A^#^#^#þ^?^#^#°<91>h«Ú^?^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^H<95>h«Ú^?^#^#P)»Ó
"
my code is:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc , char *argv[]){
int fd1,fd2,fdout;
int fread1, fread2;
char buff[128];
int fconf(int f1, int f3){
fd1 = open(argv[1],O_RDONLY);
fdout = open(argv[2],O_RDONLY | O_CREAT | O_APPEND | O_RDWR);
fread1 = read(fd1,buff,sizeof(buff));
write(fdout,buff,sizeof(buff));
close(fd1);
close(fdout);
return 0;
}
}
I have no idea why this happens.
Probably your input file contains less than 128 bytes. But you always attempt to write all 128 bytes from your buffer to your output file. Bytes after what was read are uninitialized garbage.
Use the return value of read to know how many bytes you actually got.
Related
This question already has answers here:
How to truncate a file in C?
(6 answers)
Closed 11 months ago.
I would like to write a function able to delete contents of files.
I have some thoughts of how to do it and here is the program that come up from them:
/*fclr - clear file contents*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char* argv[]){
int fd;
if(--argc == 0)
fprintf(stderr, "Incorrect syntax. Usage: cat <filename1> <filname2> ... <filenameN>.\n");
while(--argc > 0){
char c = EOF;
if((fd = open(*++argv, O_WRONLY, 0)) == -1)
fprintf(stderr, "Unable to open the file.\n");
lseek(fd, 0, SEEK_SET); //lseek here is redundant.
write(fd, &c, sizeof(char));
close(fd);
}
}
Basically, I suppused, if a file is seen a very big array of characters, is has to have and end in memory. So as well as \0 works for stings, I thought EOF will do for actual files, but is not working. After the file is ran, the content is still there.
Do you have any suggestion to solve this problem.
(I do know that opening a file with fopen on "w" mode will delete the whole content, but I would like to achieve the same result with low level functions)
Why don't you only try to open as following? It truncates the file as you expect.
open(*++argv, O_TRUNC | O_WRONLY);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a file y.txt that contains the text abcdefgh
this code convert file descriptor(int fd) to file pointer (FILE*), and tries to read from it.
#include <stdio.h>
#include<fcntl.h>
int main()
{
FILE *fp;
int fd = open("y.txt",O_RDONLY);
printf("%d",fd);
fp=fdopen(fd,"r");
close(fd);
char a[5];
a[4]='\0';
fread(a,2,1,fp);
printf("%s",a);
return 0;
}
The program outputs p instead of ab, as it should if it is reading from the begining of y.txt.
What am I doing wrong?
I see a problem with your code. You close(fd) before you are done with fp, which is probably causing your calls to fread to fail. This is because when you use fdopen:
The file descriptor is not dup'ed.
meaning that the underlying file that fp is trying to read from gets closed when you run close(fd). To fix this, you can remove the call to close and add a call to fclose which should close fd as well.
if you really just want a FILE * you should just be able to use fopen to open it, skipping the fd all together.
Consider your code:
char a[5];
a[4]='\0';
fread(a,2,1,fp);
This gives you a 5 character string. It is an "auto" variable and is not initialized. Then you terminate the string with a '\0'. Good. Then you fread one item of size 2. So bytes 3 and 4 are still garbage. Does this help?
Here are a few corrections to the program, as commented in the code.
#include <stdio.h>
#include <io.h> // added header
#include <fcntl.h>
int main()
{
FILE *fp;
int fd = open("y.txt",O_RDONLY);
printf("%d\n",fd); // add a newline for clarity
fp=fdopen(fd,"r");
//close(fd); // do not close before reading!
char a[5];
a[4]='\0';
fread(a,4,1,fp); // read 4 chars to fill the string space
printf("%s\n",a); // add a newline for clarity
close(fd); // close after reading
return 0;
}
File input:
abcde
Program output:
3
abcd
Although it would be better in the first place to have the simpler
FILE *fp = fopen("y.txt", "r");
So I am trying to do some very simple read/writes on a file. Since it's for an assignment I can't use more sophisticated functions using File*.
I can easily create a file and write to it but if I try to read back my content (it's the same content but my problem boils down to this) I don't get what I expect and I can't yet see why.
Here the code snippet that causes me problems:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char** argv){
int fdisk = open("testfile.txt", O_RDWR | O_CREAT | O_APPEND);
char buff [20] = "Just a short text!!!";
write(fdisk, buff, sizeof(buff));
char buff2[20];
read((fdisk), buff2, sizeof(buff2));
printf("Context of deleted file: %c\n",buff[1]);
printf("Context of deleted file: %c\n",buff2[1]);
return 0;
}
When you create a file you need to specify the file access mode:
int fdisk = open("testfile.txt", O_RDWR | O_CREAT | O_APPEND, 0666);
Otherwise the access mode is some indeterminate value.
And before reading it back you need to rewind it:
lseek(fdisk, 0, SEEK_SET); // rewind
The problem is that the write call leaves the file descriptor pointing to just after the data written (so more writes will go after that rather than overwriting the same data), so the following read call tries to read data after that which was written, and probably gets nothing.
I think it is a combination of issues:
You are not rewinding or re-opening the file, so when you read you are always reading from the end of the file.
You are using append mode, so it will add data to the end of the file. This means that after the first run you will be writing data at the end of the file but always reading from the beginning (assuming you address the first problem).
You are not setting the permissions, so you get random file permissions and the file may not be readable after creating it.
Your print statement is only printing the second character from each buffer, rather than a full string.
Here is a minimal working example. This compiles and runs with the expected results on my machine.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char** argv){
int fdisk = open("testfile.txt", O_RDWR | O_CREAT, 0666);
char buff[] = "Just a short text!!!";
write(fdisk, buff, sizeof(buff));
lseek(fdisk, 0, SEEK_SET);
char buff2[sizeof(buff)];
read((fdisk), buff2, sizeof(buff2));
printf("Context of deleted file: %s\n",buff);
printf("Context of deleted file: %s\n",buff2);
return 0;
}
As a final note, the functions you are using (read/write) all return values indicating whether the operation was successful. You should check them. They would have indicated that the read operation in your problem was not actually reading any data (because it was at the end of the file).
This question already has answers here:
Reading a text file backwards in C
(5 answers)
Closed 9 years ago.
I am supposed to create a program that takes a given file and creates a file with reversed txt. I wanted to know is there a way i can start the read() from the end of the file and copy it to the first byte in the created file if I dont know the exact size of the file?
Also i have googled this and came across many examples with fread, fopen, etc. However i cant use those for this project i can only use read, open, lseek, write, and close.
here is my code so far its not much but just for reference:
#include<stdio.h>
#include<unistd.h>
int main (int argc, char *argv[])
{
if(argc != 2)/*argc should be 2 for correct execution*/
{
printf("usage: %s filename",argv[0[]);}
}
else
{
int file1 = open(argv[1], O_RDWR);
if(file1 == -1){
printf("\nfailed to open file.");
return 1;
}
int reversefile = open(argv[2], O_RDWR | O_CREAT);
int size = lseek(argv[1], 0, SEEK_END);
char *file2[size+1];
int count=size;
int i = 0
while(read(file1, file2[count], 0) != 0)
{
file2[i]=*read(file1, file2[count], 0);
write(reversefile, file2[i], size+1);
count--;
i++;
lseek(argv[2], i, SEEK_SET);
}
I doubt that most filesystems are designed to support this operation effectively. Chances are, you'd have to read the whole file to get to the end. For the same reasons, most languages probably don't include any special feature for reading a file backwards.
Just come up with something. Try to read the whole file in memory. If it is too big, dump the beginning, reversed, into a temporary file and keep reading... In the end combine all temporary files into one. Also, you could probably do something smart with manual low-level manipulation of disk sectors, or at least with low-level programming directly against the file system. Looks like this is not what you are after, though.
Why don't you try fseek to navigate inside the file? This function is contained in stdio.h, just like fopen and fclose.
Another idea would be to implement a simple stack...
This has no error checking == really bad
get file size using stat
create a buffer with malloc
fread the file into the buffer
set a pointer to the end of the file
print each character going backwards thru the buffer.
If you get creative with google you can get several examples just like this.
IMO the assistance you are getting so far is not really even good hints.
This appears to be schoolwork, so beware of copying. Do some reading about the calls used here. stat (fstat) fread (read)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
struct stat st;
char *buf;
char *p;
FILE *in=fopen(argv[1],"r");
fstat(fileno(in), &st); // get file size in bytes
buf=malloc(st.st_size +2); // buffer for file
memset(buf, 0x0, st.st_size +2 );
fread(buf, st.st_size, 1, in); // fill the buffer
p=buf;
for(p+=st.st_size;p>=buf; p--) // print traversing backwards
printf("%c", *p);
fclose(in);
return 0;
}
I tried using the following code to read a text from the keyboard and write it into the file text.dat. The file was created but it was empty.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#include <string.h>
int main()
{
char s[201];
int n,f = open("text.dat", O_RDWR | O_CREAT);
while (fgets(s,200,stdin) != NULL)
write(f, s,sizeof(s));
close(f);
return 0;
}
write(f, s, strlen(s))
Though I'd use read() instead of fgets() and used its result instead of strlen()
The write is wrong. Try this:
write(f, s, sizeof(s));
The second parameter should be a pointer to the beginning of s. What you're actually passing is a pointer to the pointer.
While you're at it, get rid of that unused int n:
int f = open("text.dat", O_RDWR | O_CREAT);
Edited to add
Your write() must use strlen() instead of sizeof() - you're probably writing out uninitialized junk, which makes it appear that the file is empty.
write(f, s, strlen(s));
You are opening file in wrong way. Try open("text.dat", O_RDWR | O_CREAT,0666 );
P.S.
You simply don't have write access to file.