0

I'm pretty new to C, and I'm not sure what is wrong with this piece of code I have written. It is supposed to open (or create if needed) a file using a name specified and in that file write a bunch of signs taken from the /dev/urandom file. I need a precise amount of elements each one of a specified length. I need to be able to later edit that created file, but I wanted to focus on creating this generator part first. It doesn't show any errors when compiling or when I try to execute it, but still nothing happens - the file still doesn't exist anywhere. What's wrong with it?

int main(){

     void generate(char str[], int a, int b);

}


void generate(char str[], int a, int b){
    int n=0;
    char fname[128];
    strcpy(fname,str);
    strcpy(fname, ".txt");
    FILE *myFile = fopen(fname, "w");
    FILE *randomiser = fopen("/dev/urandom", "r");
   
    char bufor[a];
    size_t result = fread (bufor, b, a, randomiser);
    size_t end = fwrite (bufor, b, a, myFile);
   
    fclose(myFile);
    fclose(randomiser);
}

@edit change the tile as someone suggested and changed a code a bit since im still trying to work it out I forgot to mention that the whole point of this function is for it to be called in terminal as for example ./program generate data 100 100.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
Samokythr
  • 45
  • 4

3 Answers3

0

Here is the exact solution you asked for

There you go. I use open instead of fopen, read a certain amount of char out of /dev/urandom then write it to fd2 (the file created),

Be carefull the size of the buffer, be careful The NULL (\0) terminate the string

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

int generate(char **av)
{
    int fd1 = open("/dev/urandom", O_RDONLY);
    int fd2 = open(av[1], O_CREAT | O_RDWR, S_IRWXU);
    int size = atoi(av[2]);
    int row = atoi(av[3]);
    int i = -1;
    int j = -1;

    if (fd1 == -1 || fd2 == -1 || size <= 0 || row <= 0 )
        return (1);
    char buf[size];
    while (++i < row-1)
    {
        read(fd1, buf, size);
        buf[size -1] = '\0';
        write(fd2, buf, size -1);
        while (++j < size)
            buf[j] = '\0';
    }
    close(fd1);
    close(fd2);
    return (0);
}

int main(int ac, char **av)
{
    int s;

    if (ac < 4)
        return (1);
    generate(av);
    return (0);
}

for 10 * 100 char into file 'blabla' Use with :

$~> gcc prog.c -o program

$~> ./program blabla 100 10

Will create / open the file "blabla" read 100 from /dev/uramdom and wirte to blabla

To explain what you did wrong here look :

This is a declaration of a function

void generate(int i, char *a);

This is a call to a function

generate(25, "Blablabla");

sometime when you declare a function you also instanciate it aswell

int generate(int i, char *a)
{
    Operation;
    operation;
    return (0);
}

Declaration, and instanciation are different, let's assume i wrote funtion generate under function main in the above code example, function main would not know what is "generate" but if you declare it before main just like this it works

void generate(int i, char *a);
Arthur
  • 86
  • 1
  • 9
  • 2
    "Regular" `open` is not so regular. Of the two, `fopen` is the only one defined by the C standard. – John Bollinger Nov 02 '20 at 18:46
  • @JohnBollinger Note that open is Actually a System call ^^ "fopen() calls open() in the background" https://stackoverflow.com/questions/1658476/c-fopen-vs-open#:~:text=fopen()%20calls%20open(),such%20as%20built%2Din%20buffering. Off the two only Open come from the system Kernel The same for read() write() , close(), These are system call By extension the are "Regular" indeed – Arthur Nov 02 '20 at 19:27
  • 1
    There is an `open` system call on some systems, and the `open()` function is defined by POSIX. On some POSIX systems, the `open()` function operates by calling the `open` system call, and it is common on such systems to equate the two, even though they're not really the same thing. And it is likely that on such systems, `fopen()` is implemented with use of `open()`. None of that changes the fact that `open()` is not defined by C, and `fopen()` is the *regular* C function for opening files. – John Bollinger Nov 02 '20 at 19:33
  • Well as i sayed : fopen make a call to open, https://www.gnu.org/software/libc/manual/html_node/Opening-and-Closing-Files.html open is defined in the libc, open is a POSIX standard, every system that has fopen() has open() fopen = open++ thats all, saying that one is more regular than an other, i dont think it's relevant ^^ /!\ Windows also support open() /!\ ... ... Interestingly, the man page for open is in the 2nd section while the man page for fopen is in the 3rd section. – Arthur Nov 02 '20 at 19:55
  • Yet you're right open() is not mentionned in this document http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf Also i can show you the implementation of the function fopen() if you want : https://android.googlesource.com/platform/bionic/+/ics-mr0/libc/stdio/fopen.c Take a look at it – Arthur Nov 02 '20 at 20:06
  • @JohnBollinger Take a look at it Line 53 `f = open(file, oflags, DEFFILEMODE)` – Arthur Nov 02 '20 at 20:12
  • It is entirely beside the point whether any particular C standard library implements `fopen()` by use of `open()`. It is beyond doubt that there are others that do not, since there are systems that do not provide an `open()` function at all. Windows, for example. My objection was to you characterizing `open()` as more "regular" (your word) than `fopen()`, when it is in fact the reverse. You have since edited that out of the answer, so that objection is moot. – John Bollinger Nov 02 '20 at 20:22
  • Windows implement open i think, i've used it myself already – Arthur Nov 03 '20 at 18:45
  • Windows does not provide `open()`, or at least they have not always done. It does provide a similar function named `_open()`, however. Any way around, there is no reason to think that `fopen()` in the Microsoft runtime library uses `_open()` *or* `open()`, instead of going directly to a WinAPI function. – John Bollinger Nov 03 '20 at 18:47
0

Here's what I made out of your source code with minimal changes

#include <stdio.h>

void generate(char basename[], size_t size);

int main(void) {
    generate("foobar", 42);
}

void generate(char basename[], size_t size) {
    char fname[128];
    sprintf(fname, "%s.txt", basename);

    FILE *myFile = fopen(fname, "w");
    FILE *randomiser = fopen("/dev/urandom", "r");

    char bufor[size];
    size_t result = fread(bufor, 1, size, randomiser);
    fwrite(bufor, 1, result, myFile);

    fclose(myFile);
    fclose(randomiser);
}
pmg
  • 106,608
  • 13
  • 126
  • 198
0

The problem is that your program never calls the generate() function, as @fredrik pointed out in comments. This:

     void generate(char str[], int a, int b);

is a function declaration, not a call. Although it is legal to put such a declaration inside a function, it is much more conventional to put it outside and preceding the function(s) that will be doing the calling. And in this case, you could avoid using a separate declaration at all by just moving the main() function to the end, after the definition of generate().

But that still doesn't get around the fact that you need to call the function if you want it to do anything. And to call it, you will need to provide arguments. For example,

generate("random_data", 10, 4);

From your description, you'll want to use arguments determined from evaluation of command-line parameters, but that aspect would be a separate question.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157