Printing to text file but file remains empty - c

#include <stdio.h> //for printf
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
//#define STDOUT_FILENO 1
// define STDERR_FILENO 2
int main(){
// mode_t mode = S_IROTH | S_IRUSR | S_IWUSR;
mode_t mode = S_IRUSR | S_IWUSR;
close(1);
int fildes = open("hello_world.txt", O_CREAT | O_TRUNC | O_RDWR, mode);
printf("Hi! My Name is \n" );
close(fildes);
return 0;
}
From what I learned, "Hi! My Name is" should be printed to "hello_world.txt". It works well in Linux virtual machine which my professor provided.
But in my machine (I'm using remote WSL in vscode), "hello_world.txt" is empty. Can I fix this problem?

printf does not necessarily write anything. Typically, it buffers data and defers writes until the buffers are full. stdout is automatically flushed when the process exits, but you've closed the file descriptor before that happens, so the write fails. Try fflush(stdout) before you close the underlying file descriptor. (This assumes that the hacky open actually gives you the underlying file descriptor of stdout. That should happen and in most cases will, but it certainly is not guaranteed. You should use freopen if you want to do this reliably.)

Related

Error in the systemcalls C11 for do file i/o

Hi I'm on Linux WSL Debian and I've the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
int fd = open("file.dat", O_RDONLY | O_WRONLY);
write(fd, "ciao", strlen("ciao"));
close(fd);
}
Why don't works?
Many bugs:
Must include unistd.h for the declaration of write.
O_RDONLY and O_WRONLY (and O_RDWR) are mutually exclusive. If you want to open a file for read and write you have to use O_RDWR. Since you are not actually reading from the file, you should use O_WRONLY alone.
It is very rare to want to use O_WRONLY without O_CREAT and one (exactly one; these three are also mutually exclusive) of O_APPEND, O_EXCL, and O_TRUNC. Assuming that you do want O_CREAT, you must also supply a third argument, which should be the octal constant 0666 unless you have a specific reason to use some other value.
write(fd, "ciao", strlen("ciao")) should be write(fd, "ciao\n", strlen("ciao\n")) unless you have a specific reason to be creating a text file with an incomplete last line.
Because you are writing to a file, you need to check for errors on all three of the open, write, and close calls. (The fact that close can fail is a bug in its specification, but one that we are permanently stuck with. It's safe to ignore errors in close for files that were opened for reading, but not writing.)
Also some style corrections:
The code as shown only needs unistd.h, fcntl.h, and string.h; it should also be including stdio.h, because it should also be making calls to perror. None of the other headers should be included (unless this is cut down from a much larger program).
Declare main as int main(void) unless you are actually going to use argc and argv.
Don't use the C99 license to fall off the end of main; the last line of main should be return 0;.
For historical reasons, in C, the opening curly brace of a function definition should always be placed on a line by itself, even if all other opening curly braces are "cuddled" with their parent control flow construct.
You need the header <unistd.h> to get the declarations of write() and close(). The only other header you need is <fcntl.h> for open().
I've also kept <stdio.h> so I can use perror() if open() fails.
Since you're only writing to the file, you don't need O_RDONLY in the open modes. If you want to read and write, you should use O_RDWR instead. These three flags are mutually exclusive.
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
int fd=open("file.dat",O_WRONLY);
if (fd < 0) {
perror("open failed");
return 1;
}
write(fd,"ciao",strlen("ciao"));
close(fd);
}
Note that this will not create the file if it doesn't already exist. If you want that, you need to add the O_CREAT flag and another argument with the permissions that should be given to the file if it's created.

Error message when trying to use Open Function call

As part of my homework, I need to create a small c program for XV6. This program has to create a file, write to it, then close it.
When I try and compile the xv6 with my file I am receiving two error message.
HWC2.c:13:82: error: ‘O_CREAT’ undeclared (first use in this function)
fd = open("/home/kyle/Desktop/Projects/'Assignment 2'/xv6/Tom.txt", O_RDWR | O_CREAT);
^
HWC2.c:13:14: error: called object ‘open’ is not a function or function pointer
fd = open("/home/kyle/Desktop/Projects/'Assignment 2'/xv6/Tom.txt", O_RDWR | O_CREAT);
I'm new to C programming so I'm limited to what I can find with a google search and nothing there has helped. Instead, of O_CREAT I did try just using write.
#include "types.h"
#include "stat.h"
#include "user.h"
int open;
int fd;
int main (void)
{
printf(1,"My Name\n");
fd = open("/home/kyle/Desktop/Projects/Assignment 2/xv6/Tom.txt", O_RDWR | O_CREAT);
write(fd, "1 2 3 4", 7);
close(fd);
}
I need it to compile, print my name, create the file, write to the file, then save and close the file
Try including
#include <fcntl.h>
#include <stdio.h>
For printing name you could try:
printf("%s\n", "My Name");

C: How to append data to a file without using standard I/O libraries [duplicate]

This question already has an answer here:
Opening file in Append mode : using open() API
(1 answer)
Closed 5 years ago.
I was wondering if there is a way to append data to a file without using functions from standard I/O libraries (i.e. stdio.h). I though of doing something like this first:
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("test.txt", O_WRONLY | O_CREAT, 0700);
ssize_t wr = write(fd, "hello world", sizeof("hello world");
}
But this only writes data to the file without appending it so instead repeatedly displaying "hello world", it only overwrites the previous data and displays it once. Can someone please help me out? Thanks
Try this:
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main() {
int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0700);
ssize_t wr = write(fd, "hello world", strlen("hello world");
exit(0);
}

Unix/C: put a file into shared memory

Have a problem.
I have a file which contents look like number:error_description.
Now i need to put this file to shared memory (POSIX). If any contents are modified it should be saved to the base-file.
There is a need to search in the content in the shared memory (results will be sent to a client over a message queue).
How do I implement all this? First I thought I have to open (fopen("my_file", "r")) and then I have to create shared memory and mmap the file.
Can someone help me?
edit:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <semaphore.h>
/*
* \ /tmp/errors -> Error File
*/
#define MSGQ_HANDLER "/error_handler"
#define PATH_TO_FILE "/tmp/errors"
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(void) {
int fd = open(PATH_TO_FILE, O_RDWR);
struct stat file_stat;
fstat(fd, &file_stat);
printf("File size: %zd\n", file_stat.st_size);
char *byte_ptr = mmap(NULL, file_stat.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if(byte_ptr == MAP_FAILED){
perror("error:");
}
while(1){
printf("%s\n", byte_ptr);
if(byte_ptr)
exit(1);
}
return EXIT_SUCCESS;
}
So far it is what I have now.
Read a line works.
How do I change the content?
Don't use fopen and forget about shared memory (the sh* API I mean). mmap is all that's needed.
Open your file with open and the right options (read/write). Then use mmap with the option MAP_SHARED. All changes in the file will be reflected directly and visible to all processes that map the same file. On Linux and Solaris (on other systems I don't know, but it is not guaranteed by POSIX or any standard) you can even access the file concurrently with read/write. It is a bad idea though.
Concurrent memory accesses from different processes will, of course, need synchronisation (mutex, semaphores etc.).

Using MinGW how can I create a file without the read-only file attribute?

When I attempt to overwrite an existing file, I get a "permission denied" error.
I noticed that the file which is created has the "Read-only" attribute set. When I manually unset this I can then overwrite the file. Is there some flag I can pass to open() which will automatically unset this when I create a file?
Below is a bare bones example which illustrates the problem. The first run works, but the second produces the "permission denied" error.
Thanks,
Zach (New to MingW/Windows 7)
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char ** argv) {
int fid;
double data = 12.0;
if ( (fid = open("junk.data", O_WRONLY | O_CREAT | O_BINARY)) == -1 ) {
printf("ERROR opening.\n\terror is:%s\n", strerror(errno));
return 1;
}
write(fid, &data, sizeof(double));
close(fid);
return 0;
}
I tried both 0644 and S_IRUSR | S_IWUSR (with sys/stat.h included) and either works.
Make sure that you actually add it as third argument of open, instead as new term into the surrounding parentheses (as happened for me first, and compiles just fine)
open has a three-parameter variant:
int open(const char *pathname, int flags, mode_t mode);
That third parameter allows you to specify the mode bits on Unix-type systems, but should be enough to set minimal r/w permissions on windows. (Check out the man page for details.)

Resources