You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言scanf("%s")读取字符串仅输出空格前内容的原因咨询

问题原因

scanf("%s", p_texto2)的默认读取规则是从当前输入位置开始读,遇到任意空白字符(空格、换行符、水平制表符等)就立刻终止读取,不会把空白字符及后面的内容写入目标内存。
你输入Hello world时,函数读到Hello后面的空格就停止了,所以p_texto2里只存了Hello,自然读不到带空格的完整内容。
你输出里出现两次Hello也很好解释:第一次printf("%s", p_texto2)打印了一次读到的Hello,后面的while循环逐字符遍历p_texto2又打印了一次Hello,和空格后的内容没有关系。

另外你的代码还有三个隐藏风险:

  • malloc(tamano)申请内存时没有给字符串末尾必须的\0终止符预留位置,输入长度接近tamano时会出现内存越界
  • 申请的堆内存使用完没有调用free()释放,会造成内存泄漏
  • 遍历字符串时直接移动了p_texto2的原始指针,后续如果要释放内存会因为指针指向错误触发异常
修正方案

要读取包含空格的整行输入,不要用scanf("%s"),优先替换为更安全的fgets()函数,这是读取含空格输入的标准写法。如果非要用scanf实现,可以用格式符%[^\n]指定读取直到换行符才停止,但这种写法默认不做输入长度限制,很容易触发内存溢出,不推荐在正式代码中使用。

修正后的参考代码:

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

char *p_texto = "Prueba Raul";
char *p_texto2;

int main(){
    
    int tamano;
    printf("Pon el tamaño del string\n");
    scanf("%i", &tamano);
    // 吃掉scanf读数字后留在输入缓冲区的换行符,避免后续fgets直接读到空行
    getchar();
    
    // 多申请1字节空间,用于存放字符串必须的'\0'终止符
    p_texto2 = (char*)malloc(tamano + 1);
    
    printf("Escriba un texto\n");
    // 用fgets读取整行输入,支持包含空格的内容,同时限制最大读取长度避免越界
    fgets(p_texto2, tamano + 1, stdin);
    // 去掉fgets默认读入的行尾换行符
    p_texto2[strcspn(p_texto2, "\n")] = '\0';

    printf("%s\n", p_texto2);
    // 用临时指针遍历字符串,不修改p_texto2的原始指向,避免后续内存释放出错
    char *p_temp = p_texto2;
    while(*p_temp != '\0'){
       printf("%c", *p_temp);
       p_temp++;
    }

    // 释放申请的堆内存,避免内存泄漏
    free(p_texto2);
    return 0;
}

运行修正后的代码,输入Hello world即可正常打印包含空格的完整输入内容。

内容的提问来源于stack exchange,提问作者mrc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.21 16:16:01