首页 > 解决方案 > C 中的 printf 函数未按预期工作

问题描述

有人可以帮我解决这个问题吗?出于某种原因,无论我尝试什么,执行 printf 都不会在我的代码中打印。我一直在尝试使用 flush 方法,但这似乎只会导致其他问题。还有什么我可以做的吗?

int main(void) {
char **line;
size_t bufsize=MAXBUF;
printf("Type your name: ");
getline(&line,&bufsize,stdin);


}

标签: cprintf

解决方案


您正在尝试传入一个空指针,该指针在程序开始时未指向任何有意义的地址。所以这样做的问题是,即使你成功了,它也会用输入覆盖内存中的一些随机地址,这几乎肯定是你不想要的,因为它会导致分段错误或崩溃。

然而,这不是它不编译的原因。它没有编译,因为您试图将 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. 使用标准输出(刷新)更新终端的部分。

这个问题很有趣,因为 1) 成功了,但是系统在 2) 完成之前就崩溃了。


推荐阅读