关于#c语言#的问题:为什么用下面这种会报错~用gets与puts没问题

问题:输入一个整型数,然后申请对应大小空间内存,然后读取一个字符串,字符串的输入长度小于最初输入的整型数大小,最后输出输入的字符串即可

测试输入:
10
hello

img

还可以这样写吗? 这样可以运行
scanf("%s",p);
puts(p);

两个问题,一是scanf语句用%s接收的字符串,遇到空格就结束,所以字符串不能含空格,建议使用gets,直接接收一行,遇到换行符结束
二是printf输出字符串,参数应该是个数组名或字符串首地址,你写成*p的话,就是p字符串第一个字符的意思,这是不对的。gets输入的话,可以用对应的puts输出

#include <stdio.h>
int main()
{
     int n;
     scanf("%d",&n);
     char *p = (char*)malloc(n * sizeof(char));
     gets(p);
     puts(p);
}

  • 可以这样,不过scanf输入,不能有空格;
  • 打印用如下输出即可

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
int main() {
    int i;
    scanf("%d", &i);
    char *p;
    p = (char *)malloc(i);
    scanf("%s",p);
    printf("%s",p); // 不需要加 星号,直接输出p
    return 0;
}
  • 也可以用 gets输入,参考如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
int main() {
    int i;
    scanf("%d", &i);
    char *p;
    p = (char *)malloc(i);
    getchar(); // 接收上面的换行
    gets(p); // 可以有空格
    printf("%s", p);
    return 0;
}

参考GPT和自己的思路,这段代码有几个问题,以下是每个问题的详细解释:

1.scanf(_Format:"%d",&i); 这一行应该写成 scanf("%d",&i); ,因为 _Format: 是无效的语法。

2.在 malloc 函数中,应该为指针 p 分配足够的内存以存储字符串的字符,因此应该写成 p=(char*)malloc(i+1);,并在末尾添加一个空字符 '\0'。

3.在 printf 函数中,应该传递指针 p,而不是解引用指针 p,因此应该写成 printf("%s\n", p);。

下面是修复后的代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
  int i;
  scanf("%d", &i);
  char *p;
  p = (char*)malloc(i + 1);
  scanf("%s", p);
  printf("%s\n", p);
  free(p); // 释放内存
  return 0;
}

在使用 malloc 函数分配内存之后,应该使用 free 函数释放该内存,以避免内存泄漏。

回答不易,还请采纳!!!

参考GPT和自己的思路:这是因为在输出时,你使用了错误的语法。在语句printf( _Format: "%s\n",*p);中,你用了星号 * 将 p 解引用为字符,但 p 已经是指向字符数组的指针,不需要再解引用。正确的语法应该是:

printf("%s\n", p);

注意不要在格式字符串中添加多余的空格或其他特殊字符。

还有一个问题是,在使用 scanf 函数读取字符串时,应该使用 %s 格式说明符而不是 Format:。因此正确的语法应该是:

scanf("%s", p);

最终修正后的代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i;
    scanf("%d", &i);
    char *p;
    p = (char*)malloc(i);
    scanf("%s", p);
    printf("%s\n", p);
    return 0;
}


题主看下这个警告就知道为啥了,很清楚。建议C的基础好好看看

img

img

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
使用gets和puts来读取和输出字符串通常比使用scanf和printf更安全,尤其是在处理输入时(包括空格和其他特殊字符)。而且,使用scanf和printf需要指定格式化字符串,否则会有意外结果,比如字符串可能会溢出。

在这个问题中,使用scanf和printf确实可以实现目标,但是更好的选择是使用gets和puts。以下是一个使用gets和puts的示例代码:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int size;
    char* str;

    printf("请输入字符串的最大长度:");
    scanf("%d", &size);

    str = (char*)malloc(size * sizeof(char));

    printf("请输入字符串:");
    getchar(); // 读取前一个scanf的换行符

    gets(str);

    printf("输入的字符串是:%s\n", str);

    free(str);

    return 0;
}

在代码中,我们首先使用scanf从用户输入中读取字符串的最大长度,然后使用malloc函数为字符串申请空间。接下来,我们使用getchar函数来读取前一个scanf的换行符,否则在调用gets函数时可能会出现问题。然后,我们使用gets函数来读取用户输入的字符串,并使用puts函数输出输入的字符串。最后,我们使用free函数释放我们先前申请的字符串空间。

使用scanf和printf可以省略调用getchar函数的步骤,不需要处理换行符。但是,如果用户错误地输入了超过我们指定的最大长度的字符串,我们的程序可能会出现问题。此外,scanf和printf需要更多的工作来确保代码的安全性,而gets和puts只需要少量的工作来完成相同的任务。
如果我的回答解决了您的问题,请采纳!