【问题标题】:Trying to print the last element in string of numbers试图打印数字字符串中的最后一个元素
【发布时间】:2021-01-27 10:15:48
【问题描述】:

我在 C 语言中有这段代码,我将在其中输入一串用空格分隔的数字,然后用 strsep 分割它。如果我输入"1 2" 之类的字符串,并设置strcmp 在最后一个元素之前查找数字,则代码有效,但如果我设置strcmp 查找最后一个元素,则代码失败。您能提出任何修复建议吗?

char *string = malloc(1028), *found;
  if (fgets(string, 1028, stdin) != NULL) {
    while ((found = strsep(&string, " ")) != NULL) {
      if (strcmp(found, "2") == 0) {
        printf("%s\n", found);
      }
    }
  }

【问题讨论】:

  • 请提供失败案例的minimal verifiable example。您是说如果在strcmp 中使用"2",它不会按预期工作吗?如果是这种情况,则显示该代码而不是有效的代码。请注意,MVE 是完整的代码,可以完全按照所示运行以重现问题。
  • 那是因为你的最后一个元素是"2\n" 而不是"2"。在strcmp() 之前使用found[strcspn (found, "\n")] = 0;
  • 一个可能的问题是字符串末尾实际上有一个换行符。

标签: c printf strtok strcmp strsep


【解决方案1】:

这是因为found 指向的最后一个元素包含换行符。因此,您要么必须将新行添加到 strcmp,如下所示:strcmp(found, "2\n")(假设 2 是您的最后一个元素),或者当您调用 strsep 时,您需要同时标记空格和换行符:@ 987654326@.

完整的解决方案:

char *string = malloc(1028);
if (string) {
  if (fgets(string, 1028, stdin) != NULL) {
    char *p = string, *found = string;
    while ((found = strsep(&p, " \n")) != NULL) {
      if (strcmp(found, "1") == 0) {
        printf("%s\n", found);
      }
    }
  }
  free(string);
}

需要注意的几点:string 指针由strsep 函数修改,因此我更新了代码以使用中间变量p。我还更新了代码以验证分配是否成功,然后在最后释放它。根据您的系统要求,您可以考虑放弃堆并在堆栈上分配 string

【讨论】:

  • 在调用 strsep() 之前,您需要解释您必须保留指向 string 开头的指针。否则,指向已分配块开头的指针会丢失,从而造成内存泄漏。最好是char *string = malloc(1028);(验证分配),然后是char *p = string, *found = string;,然后使用found = strsep (&p, " \n");,这样就可以在完成后调用free (string);。见man 3 strsep
  • @DavidC.Rankin 好建议,我已经更新了我的答案。
猜你喜欢
  • 2013-02-16
  • 1970-01-01
  • 2022-11-20
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
相关资源
最近更新 更多