代码之家  ›  专栏  ›  技术社区  ›  backus sompnd

Malloc和scanf

  •  4
  • backus sompnd  · 技术社区  · 16 年前

    我在一些脚本语言方面相当有能力,但我终于强迫自己学习原始C语言了。我只是在玩一些基本的东西(I/O现在)。如何分配堆内存,在分配的内存中存储字符串,然后再将其吐出?这就是我现在所拥有的,怎样才能让它正常工作呢?

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
      char *toParseStr = (char*)malloc(10);
      scanf("Enter a string",&toParseStr);
      printf("%s",toParseStr);
      return 0;
    }
    

    现在我得到了奇怪的输出,比如'8'\'。

    5 回复  |  直到 16 年前
        1
  •  8
  •   FriskySaga    7 年前
      char *toParseStr = (char*)malloc(10);
      printf("Enter string here: ");
      scanf("%s",toParseStr);
      printf("%s",toParseStr);
      free(toParseStr);
    

    首先,串入 scanf 指定它将要接收的输入。要在接受键盘输入之前显示字符串,请使用 printf

    其次,你不需要取消引用 toParseStr 因为它指向一个大小为10的字符数组 malloc . 如果 然后 &toParseStr 是必需的。

    例如,假设您想编写一个函数来分配内存。那你就需要 & 因为您正在更改指针变量的内容(这是内存中的一个地址——您可以通过打印它的内容来自己查看)。

    void AllocateString(char ** ptr_string, const int n)
    {
        *ptr_string = (char*)malloc(sizeof(char) * n);
    }
    

    char ** ptr_string 它读作一个指针,它存储一个指针的内存位置 将 存储内存地址(在 马洛克 操作)的分配块的第一个字节 n 字节(现在它有一些垃圾内存地址,因为它是未初始化的)。

    int main(int argc, char *argv[])
    {
      char *toParseStr;
      const int n = 10;
      printf("Garbage: %p\n",toParseStr);
      AllocateString(&toParseStr,n);
      printf("Address of the first element of a contiguous array of %d bytes: %p\n",n,toParseStr);
    
      printf("Enter string here: ");
      scanf("%s",toParseStr);
      printf("%s\n",toParseStr);
      free(toParseStr);
    
      return 0;
    }
    

    第三,建议释放分配的内存。即使这是您的整个程序,并且当程序退出时内存将被释放,这仍然是一个好的实践。

        2
  •  9
  •   Jerry Coffin    16 年前

    你需要付出 scanf 一种转换格式,这样它就知道你想读取一个字符串——现在,你只是在显示你分配的内存中发生的任何垃圾。与其试图描述所有的问题,这里有一些代码至少应该是接近工作的:

    char *toParseStr = malloc(10);
    printf("Enter a string: ");
    scanf("%9s", toParseStr);
    printf("\n%s\n", toParsestr);
    /* Edit, added: */ 
    free(toParseStr);
    return 0;
    

    编辑:在这种情况下, free 但正如其他人所指出的那样,这并没有什么真正的区别 是 尽管如此,还是要养成一个好习惯。

        3
  •  5
  •   paxdiablo    16 年前

    使用 scanf() fscanf() 在不受控制的数据上,使用标准的“%s”说明符几乎是一种让自己陷入缓冲区溢出问题的方法。

    我积极劝阻使用不能提供保护的功能。我强烈建议你(尤其是作为一个C的新手)使用 fgets() 读取您的输入,因为您可以用它控制缓冲区溢出容易得多,它更适合于简单的行输入比 扫描() .

    一旦你有了电话,你就可以打电话了 sscanf() 顺便说一句,在这种情况下,你不需要这样做,因为你只得到一个原始字符串。

    我会用:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BUFFSZ 10
    
    int main(int argc, char *argv[]) {
      char *toParseStr = malloc(BUFFSZ+2);
      if (toParseStr == NULL) {
          printf ("Could not allocate memory!\n");
          return 1;
      }
      printf ("Enter a string: ");
      if (fgets (toParseStr, BUFFSZ+2, stdin) == NULL) {
          printf ("\nGot end of file!\n");
          return 1;
      }
      printf("Your string was: %s",toParseStr);
      if (toParseStr[strlen (toParseStr) - 1] != '\n') {
          printf ("\nIn addition, your string was too long!\n");
      }
      free (toParseStr);
      return 0;
    }
    
        4
  •  3
  •   Sanjay Manohar    16 年前

    你不需要医生 & toParseStr 在里面 scanf 因为它已经是一个指针了

    free(toParseStr) 之后

        5
  •  0
  •   sarnold    16 年前

    scanf(3) 获取格式字符串,就像 printf(3) ,不是要为用户打印的字符串。第二,传递指针的地址 toParseStr ,而不是指针 托帕塞斯特

    malloc(3) .

    您的程序仍然需要改进的地方是使用 的 a

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
      char *toParseStr = malloc(10);
      printf("Enter a short string: ");
      scanf("%s",toParseStr);
      printf("%s\n",toParseStr);
      return 0;
    }