【问题标题】:Getting string with C function用 C 函数获取字符串
【发布时间】:2017-05-10 00:06:14
【问题描述】:

我需要动态获取字符串,但由于我需要获取多个字符串,因此我需要使用函数。到目前为止我写了这个 (我把 //**** 放在我认为可能是错误的地方)

char* getstring(char *str);

int main() {

    char *str;
    strcpy(str,getstring(str));//*****
    printf("\nString: %s", str);
    return 0;
}

char* getstring(char str[]){//*****
    //this part is copy paste from my teacher lol
    char c;
    int i = 0, j = 1;
    str = (char*) malloc (sizeof(char));
    printf("Input String:\n ");
    while (c != '\n') {//as long as c is not "enter" copy to str
        c = getc(stdin);
        str = (char*)realloc(str, j * sizeof(char));
        str[i] = c;
        i++;
        j++;
    }
    str[i] = '\0';//null at the end
    printf("\nString: %s", str);
    return str;//******
}

函数中的printf 正在工作,但在main 函数中没有返回。 我尝试返回void,摆脱*s 或添加,创建另一个str2 并在那里找到strcpy,或者根本不使用strcpy。似乎没有任何工作。我错过了什么吗?或者这根本不可能 //非常感谢您的回答

【问题讨论】:

标签: c string function


【解决方案1】:

可以从这个answer获取字符串部分。仅将 \n 作为 getline 函数的输入。

char * p = getline('\n');

三件事:- 不要强制转换malloc,检查malloc/realloc是否成功,sizeof不是函数。

【讨论】:

  • sizeof 可能不是函数,但确实遵循函数的语法!就像 C# typeof() 内置关键字
  • @PaulStelian.: 是的
【解决方案2】:

问题不在于您使用的函数,而在于您尝试将其结果复制到未初始化指针的方式。

好消息是您不必复制 - 您的函数已经在动态内存中分配了一个字符串,因此您可以直接复制指针:

char *str = getstring(str);

这应该可以解决崩溃问题。为了使您的功能更好,需要考虑几点:

  • main 完成后需要free(str) 以避免内存泄漏
  • realloc 结果存储为临时指针,并执行 NULL 检查以正确处理内存不足的情况

【讨论】:

    【解决方案3】:

    就目前的情况而言,有两点值得我们借鉴:

    (1) 你应该有一种方法来返回对新字符串的引用,或者作为通过引用传递给函数的参数,或者作为返回值;你不应该同时实现。

    (2) 因为你的老师给你的子程序在堆上分配内存,所以你的程序的任何部分都可以使用它,你不必自己分配任何内存。您应该研究堆内存、全局内存和自动(堆栈)内存之间的区别,以便了解它们之间的区别并了解如何使用每种类型。

    (3) 因为内存已经分配在堆上,所以不需要复制字符串。

    鉴于这些事实,您的代码可以简化为如下所示:

    int main() {
    
        char *str = getstring();
        printf( "\nString: %s", str );
        return 0;
    }
    
    char* getstring(){
       .... etc
    

    展望未来,您需要考虑如何在程序中取消分配内存。例如,在这段代码中,字符串永远不会被释放。考虑取消分配您分配的任何内存的策略是一个好习惯。

    【讨论】:

      【解决方案4】:

      让我们稍微简化一下代码:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      char* getstring()
      {
          char c = 0;
          int i = 0, j = 2;
          char *str = NULL;
      
          if ((str = (char*) malloc(sizeof(char))) == NULL)
              return NULL;
      
          printf("Input String: ");
          while (c = getc(stdin)) {
              if (c == '\n') break;
      
              str = (char*) realloc(str, j * sizeof(char));
              str[i++] = c;
              j++;
          }
          str[i] = '\0';
          printf("getstring() String: %s\n", str);
          return str;
      }
      
      int main()
      {
          char *str = getstring();
          printf("main() String: %s\n", str);
          free(str);
          return 0;
      }
      

      然后执行:

      $ make teststring && ./teststring 
      cc     teststring.c   -o teststring
      Input String: asdfasfasdf
      getstring() String: asdfasfasdf
      main() String: asdfasfasdf
      

      【讨论】:

      • 你似乎没有接受早期关于j的cmets。
      • ... 和 while (c != '\n') 第一次是未定义的行为 - 未初始化。
      • 输入的字符串包含换行符。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 2011-12-27
      • 2018-11-06
      • 1970-01-01
      相关资源
      最近更新 更多