-2

I'm having trouble setting the file pointer to the very start of a file to write some stuff at first AFTER having already written some text in it.

I've tried rewind(), fseek(), opening the file in "r+" & "a+" modes, nothing seems to work.

Here's a small recreation of the program:

#include<stdio.h>
#include<stdlib.h>

void master_globalprint(int lim)
{
    int i = 0;
    FILE* maspass;
    errno_t err;
    err = fopen_s(&maspass, "Master_Password.txt", "r+");
    if (err != 0)
    {
        printf("Error opening Master_Password.txt");
        exit(0);
    }
    rewind(maspass);
    printf("Pointing to %ld", ftell(maspass));
    while (i < lim)
    {
        fprintf(maspass, "%d", i);          //Writing the array infront of the encrypted code
        i++;
    }
    fclose(maspass);
}

void master_create()                                //To Create a Master Password
{
    int count = 0;
    char pass;
    FILE* maspass;
    errno_t err;
    err = fopen_s(&maspass, "Master_Password.txt", "a");
    if (err != 0)
    {
        printf("Error creating Master_Password.txt");
        exit(0);
    }
    printf(" Enter Master Password : ");
    while ((pass = getchar()) != EOF && pass != '\n')
    {
        count++;
        fprintf(maspass, "%c", pass);                       //The characters are then printed one by one
    }
    if (count == 0)
    {
        remove("Master_Password.txt");
        printf("Master Password cannot be empty");
        exit(0);
    }
    fprintf(maspass, "%c", (count + 33));               //To put the amount of letters into file, forwarded by 33 to reach a certain ASCII threshold and converted to char
    fprintf(maspass, "\n");
    fclose(maspass);
    master_globalprint(count);
}

void main()
{
    master_create();
}

The above functions work and print the correct values except the master_globalprint function starts printing exactly where the last function left off.

Is it because I've to use command line arguments to achieve the task? If so, can I set the command line arguments to be executed by default somehow so that if the code is distributed, the user won't have to bother?

EDIT : Added in a reproducible code sample. When I put "a" in line 31, it prints only the stuff I input and not the numbers in master_globalprint(). If I put "w", it ONLY prints the numbers in master_globalprint() and not the stuff I input.

Chase
  • 5,315
  • 2
  • 15
  • 41
  • 7
    The `"a+"` mode to `fopen()` means "all writes append at the end of file", regardless of the current position in the file before writing. If you don't want everything appended, don't use `a`; use `"r+"` or `"w+"` mode instead. Even if you use `"r+"` or `"w+"` mode, you won't be able to insert data before what's already in the file; all you can do is overwrite what's already there. – Jonathan Leffler Jul 31 '19 at 15:29
  • 2
    Even if you use `"r+"` or `"w+"` mode, you won't be able to insert data before what's already in the file; all you can do is overwrite what's already there. See [Inserting data into the middle of a file](https://stackoverflow.com/questions/10467711) or [Delete data from the middle of a file](https://stackoverflow.com/questions/50996698) for more information. – Jonathan Leffler Jul 31 '19 at 15:35
  • 7
    Off-topic, but functions such as `fopen_s()` are not really any safer than the standard functions such as `fopen()`, and the `*_s()` functions are, as implemented by Microsoft, non-standard and non-portable. – Andrew Henle Jul 31 '19 at 15:39
  • @JonathanLeffler the `r+` mode will not create the file if it doesn't already exists; the `w+` mode will truncate it if it already exists. Both sucks -- no way to `open(O_RDWR|O_CREAT)` via `fopen()`. –  Jul 31 '19 at 15:40
  • @mosvy — there's not much I can do about that except note that POSIX provides [`open()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html) and [`fdopen()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdopen.html) which give you as much control as you want (or, at least, as much control as you can have). – Jonathan Leffler Jul 31 '19 at 15:43
  • 2
    `printf("error:...` is (almost) always a bug. It should be `fprintf(stderr, "error:...` – William Pursell Jul 31 '19 at 15:48
  • 3
    `printf("Pointing to %d", ftell(maspass)); //prints 0 every time` is undefined behavior as `ftell()` returns `long int`, not `int`. You need to use `%ld`. – Andrew Henle Jul 31 '19 at 16:01
  • Perhaps `fopen` with mode `"a"` or `"a+"` and then `freopen` with mode `"r+"`. – Ian Abbott Jul 31 '19 at 16:47
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [mcve]. – S.S. Anne Aug 01 '19 at 13:34
  • Possible duplicate of [Resetting pointer to the start of file](https://stackoverflow.com/questions/32366665/resetting-pointer-to-the-start-of-file) – Rob Aug 06 '19 at 12:09
  • It's still not clear what you expect the code to do. What exactly is your input, expected output, and actual output? – dbush Aug 06 '19 at 15:30

1 Answers1

1

Here the writing mode should be w+:

err = fopen_s(&maspass, "Master_Password.txt", "a" /* w+ */);

Here you should close the file and then remove it:

if (count == 0)
{
    /*fclose_s(maspass);*/
    remove("Master_Password.txt");
    printf("Master Password cannot be empty");
    exit(0);
}

Instead of doing this, you should keep the file descriptor open and pass it to master_globalprint:

fclose(maspass);
master_globalprint(count);
/* master_globalprint(count, maspass);
 * fclose(maspass); */

Then keep reusing the open file descriptor.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • Already tried, won't let me write stuff at the very first of the file. whereas at the very least "a+" or "a" writes the stuff, just at the end, "r+" doesn't write anything at all. Even though I checked that the loop is working in debug. The file still doesn't get any prints. – Chase Aug 01 '19 at 04:21
  • @Chase You need to use the `%ld` format specifier in `printf` because `ftell` returns a `long`. Change that and try again with `"r+"`. – S.S. Anne Aug 01 '19 at 13:33
  • Done, same result :/ – Chase Aug 02 '19 at 14:52
  • @Chase Can you try this using `fopen`? I don't have Annex K available. – S.S. Anne Aug 03 '19 at 15:11
  • Tried that as well, same result again. Is there any way to achieve this through command line arguments? – Chase Aug 04 '19 at 07:00
  • @Chase No. Can you supply the full program and the contents of the file? – S.S. Anne Aug 04 '19 at 15:19
  • Sorry for the response but I added the 2 primary functions, can you tell me what's wrong now? @JL2210 – Chase Aug 06 '19 at 12:05
  • @Chase Can you possibly just create a `main` wrapper around the `master_globalprint` function and some file data that I can test? Right now, this question lacks a [mcve]. – S.S. Anne Aug 06 '19 at 13:23
  • Ok, I edited it once again, think this'll do? @JL2210 – Chase Aug 06 '19 at 15:17
  • @Chase I suppose. If not then you'll need to make the example smaller and more compact (remove stuff until the issue goes away then add it back). – S.S. Anne Aug 06 '19 at 15:31
  • @Chase The stuff in comments is what you should pay attention to here. – S.S. Anne Aug 06 '19 at 15:46