Как я могу прочитать входной строки неизвестной длины?

Если я не'т знаю, как долго это слово, я не могу написать типа char М[6];, Длина слова может быть десять или двадцать. Как я могу использовать функции scanf, чтобы получить ввод с клавиатуры?

#include <stdio.h>
int main(void)
{
    char  m[6];
    printf("please input a string with length=5\n");
    scanf("%s",&m);
    printf("this is the string: %s\n", m);
    return 0;
}

пожалуйста, введите строку длиной=5 привет это строка: Здравствуйте!

Комментарии к вопросу (2)
Решение

Введите при обеспечении динамического площадью

Е. Г.

#include 
#include 

char *inputString(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
    char *str;
    int ch;
    size_t len = 0;
    str = realloc(NULL, sizeof(char)*size);//size is start size
    if(!str)return str;
    while(EOF!=(ch=fgetc(fp)) && ch != '\n'){
        str[len++]=ch;
        if(len==size){
            str = realloc(str, sizeof(char)*(size+=16));
            if(!str)return str;
        }
    }
    str[len++]='\0';

    return realloc(str, sizeof(char)*len);
}

int main(void){
    char *m;

    printf("input string : ");
    m = inputString(stdin, 10);
    printf("%s\n", m);

    free(m);
    return 0;
}
Комментарии (38)

С компьютерами сегодня, вы можете уйти с выделением очень больших строк (сотни тысяч символов) и при этом мало что делает вмятину в компьютере'использование с памяти. Так что я бы'т беспокойтесь слишком много.

Однако, в старые времена, когда память была на вес золота, общей практикой было читать строки на куски. `помощью fgets считывает максимальное число символов из входного, но оставляет остальную часть входного буфера нетронутыми, так что вы можете прочитать все остальное из его, как вам нравится.

в этом примере, я читал куски из 200 символов, но вы можете использовать любой кусок размер вы хотите, конечно.

#include 
#include 
#include 

char* readinput()
{
#define CHUNK 200
   char* input = NULL;
   char tempbuf[CHUNK];
   size_t inputlen = 0, templen = 0;
   do {
       fgets(tempbuf, CHUNK, stdin);
       templen = strlen(tempbuf);
       input = realloc(input, inputlen+templen+1);
       strcpy(input+inputlen, tempbuf);
       inputlen += templen;
    } while (templen==CHUNK-1 && tempbuf[CHUNK-2]!='\n');
    return input;
}

int main()
{
    char* result = readinput();
    printf("And the result is [%s]\n", result);
    free(result);
    return 0;
}

Обратите внимание, что это упрощенный пример без проверки ошибок; в реальной жизни вы будете иметь, чтобы убедиться, что вход ОК, проверяя возвращаемое значение помощью fgets.

Также отметим, что в конце, если readinput рутины, никакие байты не зря; в строке точный размер памяти, он должен иметь.

Комментарии (5)

Я'вэ видел только один simple способ чтения сколь угодно длинную строку, но я'ве никогда не использовал его. Я думаю, что это идет как это:

char *m = NULL;
printf("please input a string\n");
scanf("%ms",&m);
if (m == NULL)
    fprintf(stderr, "That string was too long!\n");
else
{
    printf("this is the string %s\n",m);
    /* ... any other use of m */
    free(m);
}

В м между % и S говорит функции scanf() для измерения строки и выделить для него память и скопировать строку в это, и чтобы сохранить адрес этой выделенной памяти в соответствующий аргумент. Как только вы'вновь сделать с ней вам придется бесплатно () это.

Это'т поддерживается на каждой реализации функции scanf (), хотя.

Как уже отмечалось, самое простое решение-установить ограничение на длину ввода. Если вы все еще хотите использовать функции scanf (), то вы можете сделать это следующим образом:

char m[100];
scanf("%99s",&m);

Обратите внимание, что размер М[] должен быть хотя бы один байт больше, чем число между % и S.

Если введенная строка не является более чем на 99, то остальные персонажи будут ждать, чтобы быть прочитан с помощью еще одного вызова или остальные строки формате отошли в функции scanf()`.

Вообще то scanf () не рекомендуется для обработки пользовательского ввода. Это'ы лучше всего применять базовые структурированные текстовые файлы, созданные другим приложением. Даже тогда, вы должны знать, что вход не может быть отформатирован, как вы ожидаете, а кто-то, возможно, мешает ему пытаться сломать вашу программу.

Комментарии (3)

Если я могу предложить более безопасный подход:

Объявить буфер достаточно большой, чтобы держать строку:

user_input типа char[255];

Получить ввод пользователя в безопасность путь:

чем fgets(user_input, 255, как stdin);

Безопасный способ получения входного сигнала, первый аргумент является указателем на буфер, в которой входные данные будут храниться, второй вход функция должна читать, а третий-указатель на стандартный поток ввода, т. е. когда пользовательский ввод исходит от.

Безопасности, в частности, исходит из второго аргумента ограничения, сколько будет чтение, которая предотвращает переполнение буфера. Кроме того, чем fgets` заботится о null завершение обрабатываемую строку.

Подробнее об этой функции здесь.

Редактировать: Если вам нужно сделать какие-либо форматирование (например, преобразовать строку в число), вы можете использовать Атой после ввода.

Комментарии (2)

Безопаснее и быстрее (удвоение мощности) версия:

char *readline(char *prompt) {
  size_t size = 80;
  char *str = malloc(sizeof(char) * size);
  int c;
  size_t len = 0;
  printf("%s", prompt);
  while (EOF != (c = getchar()) && c != '\r' && c != '\n') {
    str[len++] = c;
    if(len == size) str = realloc(str, sizeof(char) * (size *= 2));
  }
  str[len++]='\0';
  return realloc(str, sizeof(char) * len);
}
Комментарии (5)

Подвести указатель символов для хранения необходимой строки.Если у вас есть некоторое представление о возможный размер строки, а затем использовать функцию

char *fgets (char *str, int size, FILE* file);`

еще можно тоже выделять память во время выполнения, используя функция malloc() функция, которая динамически запрошенной памяти.

Комментарии (0)

Я знаю, что я приехал после 4 лет, и я слишком поздно но я думаю, что у меня есть другой вариант, что кто-то может использовать. Я использовал функция getchar (), как это:-

#include 
#include 
#include 

//I had putten the main Function Bellow this function.
//d for asking string,f is pointer to the string pointer
void GetStr(char *d,char **f)
{
    printf("%s",d);

    for(int i =0;1;i++)
    {    
        if(i)//I.e if i!=0
            *f = (char*)realloc((*f),i+1);
        else
            *f = (char*)malloc(i+1);
        (*f)[i]=getchar();
        if((*f)[i] == '\n')
        {
            (*f)[i]= '\0';
            break;
        }
    }   
}

int main()
{
    char *s =NULL;
    GetStr("Enter the String:- ",&s);
    printf("Your String:- %s \nAnd It's length:- %lu\n",s,(strlen(s)));
    free(s);
}

вот пример выполнения этой программы:-

Enter the String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!!
Your String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!! 
And It's length:- 67
Комментарии (0)

у меня тоже есть решение со стандартными входами и выходами

#include
#include
int main()
{
    char *str,ch;
    int size=10,len=0;
    str=realloc(NULL,sizeof(char)*size);
    if(!str)return str;
    while(EOF!=scanf("%c",&ch) && ch!="\n")
    {
        str[len++]=ch;
        if(len==size)
        {
            str = realloc(str,sizeof(char)*(size+=10));
            if(!str)return str;
        }
    }
    str[len++]='\0';
    printf("%s\n",str);
    free(str);
}
Комментарии (1)

Прочитать прямо на выделенное пространство с помощью fgets()`.

Особая осторожность нужна, чтобы отличить успешного чтения, конец файла, ошибка ввода и памяти. Правильное управление памяти на ВФ.

Этот метод сохраняет линию'ы &#39;\П&#39;.

#include 
#include 

#define FGETS_ALLOC_N 128

char* fgets_alloc(FILE *istream) {
  char* buf = NULL;
  size_t size = 0;
  size_t used = 0;
  do {
    size += FGETS_ALLOC_N;
    char *buf_new = realloc(buf, size);
    if (buf_new == NULL) {
      // Out-of-memory
      free(buf);
      return NULL;
    }
    buf = buf_new;
    if (fgets(&buf[used], (int) (size - used), istream) == NULL) {
      // feof or ferror
      if (used == 0 || ferror(istream)) {
        free(buf);
        buf = NULL;
      }
      return buf;
    }
    size_t length = strlen(&buf[used]);
    if (length + 1 != size - used) break;
    used += length;
  } while (buf[used - 1] != '\n');
  return buf;
}

Пример использования

int main(void) {
  FILE *istream = stdin;
  char *s;
  while ((s = fgets_alloc(istream)) != NULL) {
    printf("'%s'", s);
    free(s);
    fflush(stdout);
  }
  if (ferror(istream)) {
    puts("Input error");
  } else if (feof(istream)) {
    puts("End of file");
  } else {
    puts("Out of memory");
  }
  return 0;
}
Комментарии (3)