Clear the contents of a file using low level functions [duplicate] - c

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

Related

Unsupported file after duplicating it

I wrote a VERY simple program that copies all the bytes from a selected file and write them in a new/selected file.
What I want to do is duplicate 'elaborate' (encoded) file such .jpg, .png, .mp3, .exe and so on...
The program works fine (especially using simple .txt file), here is a running example:
(Wrote and compiled in windows using mingw):
C:\Users\Computer\Desktop>duplicate.exe img.jpg file.txt
Content of file.txt:
ÿØÿà JFIF ÿÛ C


If file.txt would have been substituted with <filename>.<new_file_extention>, the program would have create the new file and copied the above content inside as in:
C:\Users\Computer\Desktop>duplicate.exe img.jpg new_img.jpg
When I try to open new_img.jpg though the OS says me that the file is not supported hence cannot be opened.
My reasoning before writing the program was the following: "At bottom level any file is just a sequence of bytes, hence copying from an existing file and pasting onto a brand new/selected file will result in actually duplicating the file avoiding any type of encoding."
Here is the code:
//The program is just a test, is not a final version, hence the absence of some error handling.
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXBYTE 2500
#define RDWRMAX 1024
int main(int argc, char **argv){
int ifd, ofd, n;
char buf[MAXBYTE+1];
if((ifd = open(*++argv, O_RDONLY, 0)) == -1){
fprintf(stderr, "Unable to open '%s'.\n", *argv);
exit(EXIT_FAILURE);
}
if((ofd = open(*++argv, O_WRONLY | O_CREAT, 0)) == -1){
fprintf(stderr, "Unable to open '%s'.\n", *argv);
exit(EXIT_FAILURE);
}
while((n = read(ifd, buf, RDWRMAX)) > 0)
write(ofd, buf, n);
}
Can anyone help me understand why this is happening and maybe suggesting some possible way to solve it? This is a learning process for me, so thanks in advance for all the useful answers to this question.

writing bad data with open(), read() and write() [duplicate]

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.

How to read an integer and a char with read() function in C?

I'm working on linux, I have a file that contains a line like this:
328abc
I would like, in C, to read the integer part (328) and the characters 'a','b','c', using only the function:
ssize_t read (int filedes, void *buffer, size_t size))
This is the only thing the file contains.
I know there are better ways to do that with other functions, but I haven't coded in C for a long time, and trying to help a friend, only this function is alowed.
How do I play with the buffer to do that?
Thanks
edit:
I understand that I need to parse the buffer manually. and my question is how?
If that's the only thing in the file. This will do:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
char buffer[6];
char intBuffer[4];
ssize_t bytesRead;
int number;
int fd;
if ((fd = open("file.txt", O_RDONLY)) == -1) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
if ((bytesRead = read(fd, buffer, 6)) == -1) {
perror("Error reading file");
exit(EXIT_FAILURE);
}
memcpy(intBuffer, buffer, 3);
intBuffer[3] = '\0';
number = atoi(intBuffer);
printf("The number is %d\n", number);
exit(EXIT_SUCCESS);
}
The following code will print "The number is 328".
Is this some kind of homework?
I am asking because there are better ways to do that than using the read function.
Anyway to answer your question, read reads size bytes from the file whose file descriptor is filedes and places them to the buffer.
It does not know anything about line breaks etc. So you need to manually find where a line ends, etc. If you want to only use read, then you need to manually parse the buffer after each call to read (supposing your files contains many lines, that you want to parse).
Beware that a line may be split between two read calls, so you need to handle that case with caution.

How do i read a file backwards using read() in c? [duplicate]

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

C Linux - Not Writing Integers

I don't know why I keep getting troubles to write an integer to a file.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
int main (int argc, char* argv[]) {
int fd, w;
int num=80;
fd=open ("file3.txt", O_CREAT|O_WRONLY, 0777);
if (fd>0) {
w=write (fd, &num, sizeof (int));
if (w==-1) {
printf ("Writing Error \n");
return EXIT_FAILURE;
}
}
close (fd);
return EXIT_SUCCESS;
}
Does anyone know what could it be?
Thanks a lot...
You're writing binary values to the file, not ascii. If you want ascii in the file, you need to sprintf it first to a char buffer, then write the char buffer. Or open your file with fopen instead of open and use fprintf.
p.s. you want close(fd) inside your if (fd > 0) { block. Also, technically the only error return of open is -1. All other values (positive, zero, negative) are success.
From your comments it is working 100% correctly: P happens to be decimal 80.
write() is outputting bytes of the integer not a decimal representation.
You might want to look at fopen and fprintf as an easy way to get what it looks like you are expecting.

Resources