How to make scanf to read more than 4095 characters as input?

We have a test application in c that takes input using scanfa string format and the string that it uses for further processing.

So far, everything worked fine, however, recently we have a condition when you need to enter more than 4100 bytes, and scanfyou need to read them, but scanfdo not read more than 4095 of stdin. The simplest form of problematic code is as follows:

#include <stdio.h>
#include <string.h>

int main()
{
    char input_array[5000];
    int len;
    printf("Enter key: ");
    scanf("%s",input_array);
    len = strlen(input_array);

    printf("Message: %s\n",input_array);
    printf("Message Len: %d\n",len);
    return 0;
}

I think this happens because it scanfcan read a maximum of two lines and one line size is 2 k. (Correct me if I am wrong).

Now this code works if we read characters from a file, but we also need to change another test code :(

4200 , scanf.

,
scanf ?
- , , ?

+4
2

, - .

, -.

. , , - .

MAX_INPUT _POSIX_MAX_INPUT;

.

, , .

, :

scanf ?

2- . scanf 4096 , - 4096 .

- , , ?

, - . scanf.


EDIT:

.

, .

:

#include <stdio.h>
#include <string.h>
#include <termios.h> 
#include <unistd.h>

int clear_icanon(void)
{
  struct termios settings;
  int result;
  result = tcgetattr (STDIN_FILENO, &settings);
  if (result < 0)
    {
      perror ("error in tcgetattr");
      return 0;
    }

  settings.c_lflag &= ~ICANON;

  result = tcsetattr (STDIN_FILENO, TCSANOW, &settings);
  if (result < 0)
    {
      perror ("error in tcsetattr");
      return 0;
   }
  return 1;
}

int main()
{
    clear_icanon(); // Changes the input mode of terminal from canonical mode to non canonical mode.

    char input_array[5000];
    int len;
    printf("Enter key: ");
    scanf("%s",input_array);
    len = strlen(input_array);

    printf("Message: %s\n",input_array);
    printf("Message Len: %d\n",len);
    return 0;
}

,

$ stty -icanon (changes the input mode to non-canonical)
$ stty icanon (changes it back to canonical)

: ( )

, , , cooked ( ) cbreak raw.

cbreak, , , , .

stty cbreak .

cbreak

curses,

$ sudo apt-get install libncurses5-dev

:

#include <stdio.h>
#include <string.h>
#include <curses.h> 

int main()
{
    initscr(); //start curses mode      
    cbreak(); //change the terminal mode to cbreak. Can also use raw();
    endwin(); //end curses mode

    char input_array[5000];
    int len;
    printf("Enter key:");
    scanf("%s",input_array);
    len = strlen(input_array);

    printf("Message:%s\n",input_array);
    printf("Message Len:%d\n",len);
    return 0;
}

-lcurses

$ gcc 1.c -lcurses
+4

ARBY: LibC . , .

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

int main()
{
  char input_array[5000];
  size_t len;
  int res;

  printf("BUFSIZ = %d\n", BUFSIZ);

  while ((res = scanf("%4095s", input_array)) == 1) {
    len = strlen(input_array);
    printf("Message Len:%zu\n", len);
  }
  return 0;
}

:

$ dd if=<(yes hi|tr -d '\n') bs=4200 count=2 of=longline
$ gcc-4.9 -O3 -g3  -W -Wall -Wextra  -std=c11 checkbuf.c -o checkbuf
$ ./checkbuf < longline
BUFSIZ = 8192
Message Len:4095
Message Len:4095
Message Len:106

, -:

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

int main()
{
  char input_array[10000];
  char *ptoarr;
  size_t len;
  int res;

  printf("BUFSIZ = %d\n", BUFSIZ);

  ptoarr = input_array;

  while ((res = scanf("%4095s", ptoarr)) == 1) {
    len = strlen(ptoarr);
    // TODO check that total length is smaller than or equal to input_array size
    printf("Message Len:%zu\n", len);
    ptoarr += len;
  }
  len = strlen(input_array);
  printf("Message Len:%zu\n", len);
  return 0;
}

, , .

+2

Source: https://habr.com/ru/post/1654906/


All Articles