Подтвердить что ты не робот

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

Если я не знаю, как долго это слово, я не могу написать char m[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
привет
это строка: hello

4b9b3361

Ответ 1

Введите, динамически сохраняя область

например.

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

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;
}

Ответ 2

С сегодняшними компьютерами вы можете с легкостью распределять очень большие строки (сотни тысяч символов), в то же время едва ли влияя на использование ОЗУ компьютера. Так что я бы не слишком волновался.

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

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

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

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 байты не теряются; строка имеет точный объем памяти, который должен иметь.

Ответ 3

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

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);
}

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

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

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

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

Обратите внимание, что размер m[] должен быть как минимум на один байт больше, чем число между % и s.

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

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

Ответ 4

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

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

char user_input[255];

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

fgets(user_input, 255, stdin);

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

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

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

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

Ответ 5

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

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);
}

Ответ 6

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

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

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

Ответ 7

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

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

//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 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 length:- 67

Ответ 8

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

#include<stdio.h>
#include<malloc.h>
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);
}

Ответ 9

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

Особое внимание следует уделять удачному считыванию, завершению файла, ошибке ввода и нехватке памяти. Необходимое управление памятью необходимо для EOF.

Этот метод сохраняет строку '\n'.

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

#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;
}