c - C 中的 printf 函数未按预期工作
问题描述
有人可以帮我解决这个问题吗?出于某种原因,无论我尝试什么,执行 printf 都不会在我的代码中打印。我一直在尝试使用 flush 方法,但这似乎只会导致其他问题。还有什么我可以做的吗?
int main(void) {
char **line;
size_t bufsize=MAXBUF;
printf("Type your name: ");
getline(&line,&bufsize,stdin);
}
解决方案
您正在尝试传入一个空指针,该指针在程序开始时未指向任何有意义的地址。所以这样做的问题是,即使你成功了,它也会用输入覆盖内存中的一些随机地址,这几乎肯定是你不想要的,因为它会导致分段错误或崩溃。
然而,这不是它不编译的原因。它没有编译,因为您试图将 char *** 传递给需要 char ** 的函数。
所以我要做的是:
#include <stdio.h>
int main(void) {
char *line=NULL;
size_t bufsize=0;
printf("Type your name: ");
if(getline(&line,&bufsize,stdin)==-1){
puts("Error: User cancelled input.");
}
else{
printf("Entered: %s",line);
}
free(line);
return 0;
}
所以这段代码所做的是它创建了一个指向字符数组的指针,但它将指针设置为指向 NULL,以便程序可以看到它没有指向任何地方,然后将其地址(&line)提供给 getline 函数,这会将 char * 类型转换为 getline 函数所需的 char **。每当你在 C 中的某个东西前面加上一个 & 时,它都会在类型中添加一个额外的 *。
你可能已经知道这一点,但是如果一个函数声明它返回一些东西,你应该总是返回一些东西,即使它是无意义的,否则取决于应该返回的类型,这有时会导致崩溃。
您使用 printf 没有任何问题,这很好。printf不一定fflush到stdout,通常\n字符会触发flush,但它是特定于实现的,所以如果你的程序在fflush写入stdout之前崩溃,那么你可能永远看不到最后一个printf。你可以试试 fflush(stdout); 在getline 函数之前,但在 getline 函数之后可能无法工作,因为在此之前它可能会崩溃。
在您的情况下,发生的事情是在 printf 写入屏幕之前 getline 获取指针的地址(或指向指针的指针),将其取消引用到指针,无法这样做,所以在您有机会之前输入它崩溃的任何击键,丢失标准输出管道,所以你最终永远不会看到你的提示。
当我在上面运行更改后的代码时,我得到:
XXXX@dell:~$ gcc Deleteme.c
XXXX@dell:~$ ./a.out
Type your name: test1
Entered: test1
XXXX@dell:~$
并且在 Linux 下可以正常运行。所有这一切的关键教训是,终端在屏幕上的更新速度很慢,所以在过去的某个时候,决定分离 printf 的功能。
printf 有两个组件:
- 将文本写入标准输出的部分。
- 使用标准输出(刷新)更新终端的部分。
这个问题很有趣,因为 1) 成功了,但是系统在 2) 完成之前就崩溃了。
推荐阅读
- mysql - 使用正确密码的 Node 应用程序连接 mysql 失败
- python - 从 tkinter 中的画布中删除数据
- angular - 在 Angular 应用程序中嵌入 SVG 图像
- google-colaboratory - 重新连接到 Colaboratory 时,我的电脑崩溃了
- c# - Pass variable values from Xamarin.Android to Xamarin.Forms
- java - 强制改造以加载新数据
- android - 是否可以使用模型查看器触发显式意图?
- python - Flask render_template not being called after Thread
- c++ - 为什么我得到“mpir_ui”没有在这个范围内声明?
- sql - SQL Server 类似模式