【问题标题】:How to read multiple strings in C one in a line, each containing spaces?如何在一行中读取 C 中的多个字符串,每个字符串都包含空格?
【发布时间】:2020-05-07 13:33:49
【问题描述】:

我分配了一个二维字符数组,在读取没有空格的字符串时,代码运行良好。当我用空格阅读它们时,我遇到了一个错误。如何读取所有 N 个字符串,每个字符串都在一行中,每个字符串都包含空格。

示例输入:

Enter total number of Strings : 3

Enter all the 3 Strings :

John Doe

Jane Doe

Trad Braversy

我的代码:

// Code to enter the total number of Strings : 
int N;
printf("\n\tEnter the total number of Strings : ");
scanf("%d", &N);

// Code for allocating initial memory to them :
char** strings = (char**)malloc(N * sizeof(char*));
for (int i = 0; i < N; ++i) {
    strings[i] = (char*)malloc(1024 * sizeof(char));
}

// Code for entering all the N strings :
printf("\n\tEnter all the %d Strings :\n", N);
for (int i = 0; i < N; ++i) {
    gets(strings[i]);
}

// Code to reallocate the memory according to the entered length :
for (int i = 0; i < N; ++i) {
    strings[i] = (char*)realloc(strings[i], strlen(strings[i]) + 1);
}

【问题讨论】:

  • 您提供的代码有效吗?有什么问题吗?
  • 从不使用gets。我想我会做一些考古学,以确定该建议何时成为常识,如果最终答案是在 1981 年之后的任何时候,我会感到惊讶。但要找到很久以前的数据可能会很困难。
  • @KamilCuk 如果我输入的字符串之间没有空格,那就可以了。如果我给 N = 3,并开始扫描带空格的字符串,它会扫描 2 并且剩余的代码正在执行,其他字符串不会被扫描。
  • @xing 不,我在循环上方添加了一个提示,说:“输入所有 N 个字符串:”,即使在那之后代码也一样。
  • @WilliamPursell 不幸的是,“Let us C”一书在印度仍然很受欢迎。我看了一眼那本书,真是太可怕了。

标签: c string malloc c-strings gets


【解决方案1】:

一些观察:

读取一整行文本,然后从中解析出整数比对单个整数执行scanf() 更安全。这是因为后者将换行符留在流中,这可能会混淆以后的读取。

使用malloc()为此进行动态内存分配没有任何意义,您可以使用VLA:

char strings[N][1024];

请注意,在 C 语言中,对运行时变量使用仅大写的符号在风格上很奇怪。

那么,使用fgets()好多了,它更安全,更好:

for (int i = 0; i < N; ++i)
{
  if (fgets(strings[i], sizeof strings[i], stdin) == NULL)
  {
    fprintf(stderr, "**Read error on string %d\n", i);
    exit(1);
  }
}

和往常一样,做好 I/O 可能失败的准备,并尝试处理它。

【讨论】:

  • 好的,我不会使用动态内存分配。但是如果我的字符串不是 1024 个字符长怎么办?不会像浪费很多内存吗?
  • @RahulSriRam 可能会。但是在您的参考代码中,您分配了 ANYWAY 1024 个字符。所以你在浪费堆内存。如果您对预期长度 + 1 个字符进行 malloc,情况会有所不同。
  • @RahulSriRam — 你的机器提供了多少 GB 的内存?您有浪费多少千字节的危险?废物占可用总量的很大一部分吗?
  • @RobertoCaboni 在读取字符串后,我使用另一个循环将每个字符串重新分配到它们的字符串长度。所以我不认为我在浪费任何空间。上面的代码我没有添加,我现在正在编辑。
  • @RahulSriRam 为什么不简单地 ONE temp 字符串 1024 字节长,然后将其复制到新分配的缓冲区 strlen(temp)+1 字节大?这样一来,您就不会因为 N 的大值而浪费堆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多