0

I have a C program in which I am trying to get the user input as a whole line and writing to a memory mapped file to implement IPC. The weird thing is when I use fgets or StrinCchGetsA the program doesn't wait for input but jumps to the next instruction right away. This weird behaviour doesn't happen if I use scanf_s with format string "%s" but this stops inout with the first space. If I use the the format string "%[^\n]s" or %[^\n]" to account for spaces the weird behaviour happens again.

Here's my main function. It is simple the user presses 1 to read from the memory mapped file or 2 to write to it.

int main()
{

    HANDLE hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1 << 16, L"Shared Memory");
    if (!hFMap)
    {
        printf_s("Error: %u", GetLastError());
        return 1;
    }
    else
    {
        void* p = MapViewOfFile(hFMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
        if (!p)
        {
            printf_s("Error getting pointer\n");
            return 1;
        }
        int ch = 0;
        bool quit = false;
        while (!quit)
        {
            printf(">>1 ");
            scanf_s("%d", &ch);
            switch (ch)
            {
            case 1:
                readMem(p);
                break;
            case 2:
                writeMem(p);
                break;
            case 0:
                quit = true;
                break;

            }
        }

    }
    return 0;
}

The problematic code of writeMem function is as follows

void writeMem(void* p)
{
    char txt[128];
    printf(">>2 ");
    fgets(txt, _countof(txt), stdin);
    strcpy_s((char*)p, _countof(txt), txt);
}

or

void writeMem(void* p)
{
        char txt[128];
        printf(">>2 ");
        scanf_s("%[^\n]s", txt, _countof(txt));
        strcpy_s((char*)p, _countof(txt), txt);
}

It displays >>2 >>1 in the command line which indicates that it didn't stop at fgets and it writes in the buffer and my variable ch.

Why is that happening?

Raafat Abualazm
  • 74
  • 2
  • 10
  • Doesn't your output start with `>>1`? How do you get to `writeMem` without passing `printf(">>1 ");`? – Gerhardh Nov 18 '21 at 12:11
  • Not related to your problem, but `_countof(txt)` in your call to `strcpy_s` is absolutely useless if you take the size of the source string. If you want to prevent a buffer overflow, you must take the size of the remaining space in the destination buffer. – Gerhardh Nov 18 '21 at 12:13
  • You might check if there is a single `\n` in your buffer after calling `fgets`. You should not mix `fgets` and `scanf` – Gerhardh Nov 18 '21 at 12:14
  • @Gerhardh I am not sure I understand what you mean? It writes >>2 then it should wait at the fgets function, but it doesn't. It goes to the strcpy then return to main a prints >>2 and waits at the scanf. – Raafat Abualazm Nov 18 '21 at 12:24
  • @Gerhardh The destination buffer is 64KB. I am using count of txt just to get used to the notation. I know it is useless. – Raafat Abualazm Nov 18 '21 at 12:25
  • @Gerhardh Yes the question is related. I didn't know that scanf leaves the final \n in the buffer. I searched for the solution now and solved. Thank you a million. – Raafat Abualazm Nov 18 '21 at 12:36
  • Your output must start with a `>>1` otherwise it does not match the code you show. The parameter in `strcat_s` is not useless if you provide the correct value. Also there is no point in using `_countof` for a character buffer. The C standard operator `sizeof` also does the trick. – Gerhardh Nov 18 '21 at 12:43

1 Answers1

0

As it turns out. scanf and scanf_s leave the final \n in the buffer. I just needed to call getchar after it to remove it. This \n was being read by fgets from the buffer causing it to stop.

        scanf_s("%d", &ch);
        getchar();
Raafat Abualazm
  • 74
  • 2
  • 10