自学c中printf出现的问题

目前在自学c,在学的过程中我

img


发现我跟着学打出来的程序按回车不会输出(printf)但是随便按一个字母在来按回车才能继续跑程序

img

img

你把 scanf 中的 \n 去掉。scanf 是原样输入,你必须输入数字(%d) 回车(\n) 才行。

所以把 \n 去掉,如果不行还需要回车 就调用 fflush(stdin);


如果有用麻烦点个采纳,谢谢~

scanf("%d\n", &grade); 这句里多了 '\n' ,应修改为:scanf("%d", &grade);

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7746735
  • 这篇博客你也可以参考下:C语言学习之printf中怎么使用可变宽度的输出字段
  • 除此之外, 这篇博客: 自己实现printf函数中的 下面解析printf函数的使用: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 这里写图片描述

    x86平台VC6.0编译器中,stdarg.h头文件内变参宏定义如下,本次实现也printf函数也采用此定义:

    变参宏根据堆栈生长方向和参数入栈特点,从最靠近第一个可变参数的固定参数开始,依次获取每个可变参数的地址。

    typedef char * va_list;
    
    #define _INTSIZEOF(n)       ( (sizeof(n)+sizeof(int)-1) & ~(sizeof(int)-1) )
    
    #define va_start(ap,v)        ( ap = (va_list)&v + _INTSIZEOF(v) )
    
    #define va_arg(ap, type)    ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )
    
    #define va_end(ap)             ( ap = (va_list)0 )

    各宏的含义如下:
    _INTSIZEOF宏考虑到某些系统需要内存地址对齐。从宏名看应按照sizeof(int)即堆栈粒度对齐,即参数在内存中的地址均为sizeof(int)=4的倍数。例如,若在1≤sizeof(n)≤4,则_INTSIZEOF(n)=4;若5≤sizeof(n)≤8,则_INTSIZEOF(n)=8。
            为便于理解,简化该宏为:

    
    #define _INTSIZEOF(n)  ((sizeof(n) + x) & ~(x))
    
    x = sizeof(int) - 1 = 3 = 0b’0000 0000 0000 0011
    
    ~x = 0b’1111 1111 1111 1100

    一个数与(~x)相与的结果是sizeof(int)的倍数,即_INTSIZEOF(n)将n圆整为sizeof(int)的倍数。

    ② va_start宏根据(va_list)&v得到第一个可变参数前的一个固定参数在堆栈中的内存地址,加上_INTSIZEOF(v)即v所占内存大小后,使ap指向固定参数后下个参数(第一个可变参数地址)。
    固定参数的地址用于va_start宏,因此不能声明为寄存器变量(地址无效)或作为数组类型(长度难定)。
    ③va_arg宏取得type类型的可变参数值。首先ap+=_INTSIZEOF(type),即ap跳过当前可变参数而指向下个变参的地址;然后ap-_INTSIZEOF(type)得到当前变参的内存地址,类型转换后返回当前变参值。
    va_arg宏的等效实现如下:

    #define va_arg(ap,t)    (ap = ap + _INTSIZEOF(t), *(t *)(ap - _INTSIZEOF(t)))
    

    ④va_end宏使ap指针指向空,防止野指针


  • 您还可以看一下 李南江老师的零基础学会C语言课程中的 printf函数输出不同类型数据(掌握)小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    问题分析:根据问题描述,程序运行时需要再输入一个字符后才能输出,可能是因为输出被缓存了,需要刷新缓存区才能输出。

    解决方法:使用fflush或者换行符进行缓存区刷新。

    代码示例:

    #include <stdio.h>
    int main(){
        int a=5;
        printf("%d\n", a); //在printf语句末尾加上换行符
        fflush(stdout);    //使用fflush函数刷新缓存区
        return 0;
    }
    

    如果要使用自定义的输出函数,可以在输出完毕后使用fflush刷新缓存区:

    #include <stdio.h>
    #include <stdlib.h>
    int my_printf(const char * fmt, ...) {
        int res=0;
        va_list arg;
        va_start(arg,fmt);
        res=vprintf(fmt,arg);
        va_end(arg);
        fflush(stdout); //使用fflush函数刷新缓存区
        return res;
    }
    int main(){
        int a=5;
        my_printf("%d\n", a); //在输出末尾加上换行符
        return 0;
    }
    

    另外,还可以使用system("pause")暂停程序以便查看输出结果,但这会影响程序的运行效率,建议在调试时使用。

    注意事项:如果是在Linux下编程,换行符为"\n";而在Windows下编程,换行符为"\r\n"。在Windows下如果使用"\n",则可能出现输出换行符\r仍在缓存区中的问题。因此,在Windows下建议使用printf("%s\n",...)代替puts(...)进行输出,或者使用fflush(stdout)进行缓存区刷新。

把输入中的\n删掉试一下

img

这个要看你的程序代码怎么写的, printf只是打印功能,你代码中可能有 getchar() 接收字符