0

我知道这是可能的

char text[A_BIG_NUMBER];
printf("Enter your name");
scanf("%s",text);

但是有没有办法做到这一点?(不使用 char 数组作为备份)

char* text;
printf("Enter your name");
scanf("%s",text);

虽然第一种方法很简单,但是如果 A_BIG_NUMBER 不足以容纳用户输入的字符串,那么它将给其余代码带来问题,另一方面,如果我们使用大数字,则会浪费内存!

谢谢

编辑:对不起,错误的标签。我只问C。

4

5 回答 5

3

既然你说 C++,答案是“是的,字符串”:

std::string name;

std::cout << "Enter your name: ";

if (!std::getline(std::cin, name)) { /* unexpected end of input */ }

// now use "name"

正如您所发现的,您通常需要动态分配来存储外部数据。(你的代码不是很通用:你不能有非常大的自动数组,固定大小会添加任意幻数和约束。) C++ 是封装动态分配和清理细节的完美语言,因此你可以使用简单的自动变量为您完成所有工作。

如果您不喜欢 iostreams,您可以安装自己的重载bool getline(std::FILE *, std::string &),循环调用std::fgets+=提取完整的行。

于 2012-10-07T13:03:57.697 回答
1

您当然可以使用动态分配的内存而不是数组,但溢出的根本问题仍然存在:

char *text = malloc(A_BIG_NUMBER*sizeof(char));
printf("Enter your name");
scanf("%s",text);

你需要告诉scanf空间是有限的,像这样:

char text[201];
printf("Enter your name");
scanf("%200s",text);

请注意,text[201]终止符有一个额外的字符空间:%200s将输入限制为 200 个“真实”字符,因此您需要char'\0'.

于 2012-10-07T13:02:57.200 回答
1

char* 不分配内存来存储用户输入字符串,这就是第二个代码不起作用的原因。

如果您担心内存使用/浪费,您可以使用程序特定的堆栈/堆来克服这些限制。

于 2012-10-07T13:06:32.003 回答
0

fgets()在循环中使用一个小的(ish)缓冲区。在循环 realloc() 内部是最终目的地。

/* UNTESTED */
char smallish[1000];
char *destin = NULL;
size_t destin_size = 1;
while (fgets(smallish, sizeof smallish, stdin)) {
    destin_size += strlen(smallish);
    char *tmp = realloc(destin, destin_size);
    if (!tmp) /* deal with error */;
    destin = tmp;
    strcat(destin, smallish);
    if (smallish[strlen(smallish) - 1] == '\n') break;
}
/* use destin */
free(destin);
于 2012-10-07T13:07:10.197 回答
0

您可以使用 getchar,这是一个示例代码:

  int size = 128;
  char *s = (char*)malloc (size);
  char c;
  int i;
  while ((c = getchar ()) != '\n' && c != EOF)
    {
      s[i] = c;
      ++i;
      if (i == size)
        {
          size = size * 2;
          char *tmp = realloc (s, size);
          if (tmp != NULL)
            s = tmp;
          else ; // error, try with malloc and copy or exit or whatever you want
        }
    }
  s[i] = 0;
于 2012-10-07T13:20:11.803 回答