Лучшие способы получить строку от пользователя - PullRequest
0 голосов
/ 24 октября 2019

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

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

int main(){
  char p[1024];   //there if i use 'char *p=(char*)malloc(sizeof(char)*1024)' error too.
  int i=0;
  fgets(p,1024,stdin); //there if i use 'scanf("%s",p)', wrong.
  while(p[i]!='\0'&&i<1024){
    printf("%c",p[i]);
    i++;
  }
  return 0;
}

можетКто-нибудь предоставит лучший способ сделать это и объяснить мою ошибку? Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 24 октября 2019

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

Вместо этого вы можете использовать новый (er) getline* 1006. *, если ваш компилятор совместим с POSIX:

#include <stdio.h>
#include <stdlib.h>
int main() {
    char *p = NULL;
    size_t size = 0;
    getline(&p, &size, stdin);
    for (int i = 0; p[i] != '\0' &&i < size; i++)
        printf("%c", p[i]);
    free(p);
    printf("size %zu",size);
    return 0;
}

Таким образом, вам не нужно беспокоиться о размере буфера. getline позаботится об этом. Вам просто нужно free память, когда вы закончите с этим.

1 голос
/ 24 октября 2019

Я хочу контролировать длину, но никак не могу

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

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

Использование fgets()

int main(void) {
  char p[1024];
  if (fgets(p, sizeof p,stdin) == NULL) {
    puts("Input closed");
    return -1;
  }
  size_t len = strlen(p);
  if (len > 0 && p[len - 1] == '\n') {  // lop off potential \n
    p[--len] = '\0';
  }
  if (len + 1 == sizeof p) {  // too long a line
    int ch;
    while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
      ; // consume rest of line
    }
    printf("Input too long, first part <%s>\n", p);
    return -1;
  }
  printf("Input OK <%s>\n", p);
  return 0;
}
...