printf如何处理其参数?我知道在C#中我可以使用params关键字来做类似的事情,但我无法在C中完成它?
我想通过阅读来学习C C程序设计语言,第2版.我有一些编程经验,但没有C.
我目前在第1章.我有以下代码:
float f;
for (f = 0.0; f <= 3; f += 1.1)
printf("A: %3f B: %6.2f\n", f, f + 0.15);
Run Code Online (Sandbox Code Playgroud)
它打印输出:
A: 0.000000 B: 0.15
A: 1.100000 B: 1.25
A: 2.200000 B: 2.35
Run Code Online (Sandbox Code Playgroud)
看起来很好.
现在我按如下方式更改printf:
printf("A: %3d B: %6.2f\n", f, f + 0.15);
Run Code Online (Sandbox Code Playgroud)
新的输出是
A: 0 B: 0.00
A: -1610612736 B: 0.00
A: -1610612736 B: -625777476808257557292155887552002761191109083510753486844893290688350183831589633800863219712.00
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我希望浮点数转换为int,因为我使用了%d,但事实并非如此.另外,为什么价值B也出错?这里发生了什么事?
c中的printf函数并不总是在屏幕上打印输出.例如,如果您忘记将\n放在字符串的末尾,那么您有时会得不到o/p.printf无法打印时是否还有其他一些条件.我记得有人说有7个这样的条件.你能帮忙吗?
我有这个代码:
#include <stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出hello-err hello-err hello-err hello-err hello-err hello-err
间隔为1秒.我想知道为什么hello-out永远不会被打印出来.
今天,我从Elance.com上做了一个简短的"C++技能测试".一个问题如下:
以下代码行的安全漏洞是什么:
printf("%s", argv[1]);选项1:格式字符串
选项2:堆栈溢出 < - 这被Elance标记为正确答案
在最初几秒钟看到问题后(或自动使问题无效),用户被提供10秒钟来回答此问题.(还有另外两个明显不相关的答案,没有被Elance标记为正确答案.)
我正在寻找缓冲区溢出或缓冲区溢出作为选项.
我本能地不喜欢答案堆栈溢出,因为在我10秒内我精神上使用了我认为是"Stack Overflow"的标准定义:
在软件中,当堆栈指针超出堆栈限制时,会发生堆栈溢出.调用堆栈可能包含有限数量的地址空间,通常在程序开始时确定...
根据"Stack Overflow"的定义,在没有堆栈溢出的情况下完全可以实现缓冲区溢出 ; 只有当程序试图在调用程序的总堆栈分配之外写入时才会发生堆栈溢出(无论是由于缓冲区溢出,还是由于它是否是合法写入,例如为基于堆栈的变量分配内存过多而次).
我的10秒本能告诉我,"缓冲区溢出"是对上面有问题的代码行的更准确的描述 - 因为通常(根据我的经验),有足够的空字符('\0')通过RAM中的垃圾数据来填充,以避免在这种情况下实际的堆栈溢出,但实现中的缓冲区溢出似乎是合理可能的,甚至可能.(但是,这可能printf在这里读的垃圾可能会认为argc == 1,这样有是没有用户提供的argv[1];如果argv[1]存在,或许可以假设很可能是调用函数还没有插入NULL的这不是在问题陈述是否.argv[1]为当下.)
因为我想象这里可能存在缓冲区溢出问题,即使没有堆栈溢出,我回答了格式字符串,因为简单地通过传递不同的格式字符串"%.8s",问题可以大部分避免,所以它看起来像一个整体更通用,因此更好,回答.
我的回答被标记为错误.正确答案标记为"Stack Overflow".
现在我想到,如果假设argv[1]存在,那么唯一可能的缓冲区溢出是堆栈溢出,在这种情况下,堆栈溢出实际上可能是正确的答案.但是,即使在这种情况下,将这称为堆栈溢出也不会被认为是奇怪的吗?缓冲区溢出是否是描述此问题的更好方法,即使假设argv[1]存在?而且,如果argv[1]是不存在的,是不是非常不正确地指出,问题是 …
考虑这个(人为的)例子:
#include <cstdio>
#include <iostream>
int main() {
volatile char test[] = "abc";
std::printf("%s\n", test);
std::cout << test << "\n";
}
Run Code Online (Sandbox Code Playgroud)
使用GCC进行编译并运行会提供以下输出:
$ g++ test.cc
$ ./a.out
abc
1
Run Code Online (Sandbox Code Playgroud)
如您所见,printf打印时正确cout打印字符串1.为什么写cout产生1在这种情况下?
这有效:
> sprintf('%d', c(1, 1.5))
[1] "1" "1"
Run Code Online (Sandbox Code Playgroud)
这不是:
> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) :
invalid format '%d'; use format %f, %e, %g or %a for numeric objects
Run Code Online (Sandbox Code Playgroud)
为什么?
我有以下代码:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
ffffffff
ffffffff
-1
-1
4294967295
4294967295
Run Code Online (Sandbox Code Playgroud)
我可以看到根据传递给printf函数的值将值解释为有符号或无符号.在这两种情况下,字节都是相同的(ffffffff).那么,这个unsigned词是什么意思?
该<stdarg.h>头文件是用来做函数接受的参数未定义的数字,对不对?
所以,必须使用的printf()功能是接受大量的论点(如果我弄错了,请纠正我).
我在gcc的stdio.h文件中找到以下行:<stdio.h><stdarg.h>
#if defined __USE_XOPEN || defined __USE_XOPEN2K8
# ifdef __GNUC__
# ifndef _VA_LIST_DEFINED
typedef _G_va_list va_list;
# define _VA_LIST_DEFINED
# endif
# else
# include <stdarg.h>//////////////////////stdarg.h IS INCLUDED!///////////
# endif
#endif
Run Code Online (Sandbox Code Playgroud)
我无法理解其中的大部分内容,但它似乎包括在内 <stdarg.h>
所以,如果printf()使用<stdarg.h>接受可变数量的参数,并stdio.h已printf(),一个C程序中使用printf()无需包括<stdarg.h>不是吗?
我尝试了一个程序,它有printf()一个用户定义的函数接受可变数量的参数.
我尝试的程序是:
#include<stdio.h>
//#include<stdarg.h>///If this is included, the program works fine.
void fn(int num, ...)
{
va_list vlist;
va_start(vlist, num);//initialising va_start (predefined)
int i; …Run Code Online (Sandbox Code Playgroud)