在 stdin 上使用 read() 检查“\n”(回车)后,我无法打印 f() 或 write() 我的数组

I can't printf() or write() my array after using a read() on stdin to check for '\n' (enter)

提问人:couscous 提问时间:11/4/2023 最后编辑:couscous 更新时间:11/4/2023 访问量:63

问:

我正在编写一个小程序,它应该打印出 sin(counter),而每次我在控制台中输入“\n”(Enter)时,counter 都会增加 0.01。

两者都不要打印任何内容到控制台。 通过调试,我发现我的代码的其余部分正在按预期工作,就在打印 sin_output[0] 之前,它填充了正确的 sin(counter) 值。printf("%lf", sin_output[0]);write(1, &sin_output, sizeof(sin_output));

我选择了一个数组,因为我希望程序稍后写入套接字或管道,据我所知,printf() 对此毫无用处。

我尝试在一个小程序中重现此错误,如下所示:

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

int main() {
  double array[1];
  array[0] = 1;
  printf("%lf", array[0]);

  return 0;
}

这将打印出正确的值。 输出: 1.000000

替换为会给出一些随机字符,这可能是由于 write() 将我的输出格式化为字符串?printf("%lf", array[0]);write(1, array, sizeof(array));

使用打印相同的胡言乱语。write(1, &array, sizeof(array));

现在我试过:array[0] = sin(x);

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

int main() {
  double array[1];
  double x = 0.01
  array[0] = sin(x);
  printf("%lf", array[0]);

  return 0;
}

出于某种原因打印 0.010000(四舍五入?

使用打印出正确的值。double x = 0.1

因此,我在最小的可重复系统中尝试了我所知道的所有选项。所有程序都至少输出一些东西,无论是错误的还是不需要的值。

但是,在我的代码中使用(几乎)完全相同的结构不会打印任何值。没有。array[1] = sin(enter_counter)

我怀疑这是由于我使用并且程序使用 stdin/stdout 缓冲区产生了一些不需要的行为,这导致 stdout 无法正确打印 for 和 。read(0, &buf, sizeof(buf))printfwrite()

我实际程序的代码是:

/* includes*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* main function*/
int main() {
  /* declare variables*/
  char buf[1];
  double enter_counter = 0;
  double sin_output[1];

  /* reset buf*/
  memset(&buf, 0, 1);

  /* master loop*/
  while (1) {
    /* read stdin*/
    read(0, &buf, sizeof(buf));

    /* if stdin == enter key, progress sin by 0.01rad*/
    if (buf[0] == 10) {
      enter_counter += 0.01;
    }

    /* reset buffer*/
    memset(&buf, 0, 1);

    /* calculate sin for enter_counter*/
    sin_output[0] = sin(enter_counter);
    
    /* printf sin(enter_value)*/
    printf("%lf", sin_output[0]); 
    //write(1, sin_output, sizeof(sin_output));
  }
}

任何帮助都是值得赞赏的。

阵列 C printf stdio

评论

4赞 Some programmer dude 11/4/2023
read并且只处理原始二进制数据。没有文本转换。write
1赞 Harith 11/4/2023
在对 的调用中添加换行符,或在它之后调用。printf()fflush()
1赞 Some programmer dude 11/4/2023
以第一个示例中的值为例。通常,一个值是 8 个字节(64 位),并且没有一个字节会包含任何接近字符串或类似内容的内容。如果写入原始二进制数据,则将写入这 8 个字节的原始值。可能它们都与漂亮的可打印 ASCII 字符相对应。array[0]double"1.0"
1赞 Fe2O3 11/4/2023
"我选择了一个数组,因为我希望程序稍后写入套接字或管道“请澄清...您的程序可以发送二进制数据(如 using )或格式化字符串(如 using )向下发送......你想达到什么目的?doublewrite()"3.14159"fprintf()
1赞 Some programmer dude 11/4/2023
让我们举一个不同的例子,值 。假设通用的 32 位将存储为四个字节或存储在内存中。如果将其写入需要 ASCII(或 UTF-8)编码字符的终端,则该字符将被写入特殊字符 () 或 ()。这些字符都不可打印,在 Windows 上,它通常打印为某些符号。int1int0x00 0x00 0x00 0x010x01 0x00 0x00 0x00NUL0x00SOH0x01

答:

2赞 Douglas B 11/4/2023 #1

您需要在打印语句中添加换行符,如下所示:

printf("%lf\n", sin_output[0]); 

这为我带来了以下结果:

$ ./a.out 

0.010000

0.019999

0.029996

0.039989

0.049979

0.059964
^C

不确定到底发生了什么,但很可能你的输出正在被缓冲,然后被你自己的换行符覆盖。查看输出缓冲以更好地理解。

评论

0赞 couscous 11/4/2023
这解决了它,谢谢。这很可能是你如何解释的。我将研究输出缓冲。祝你有美好的一天:)
2赞 couscous 11/4/2023
@Fe2O3,我想宣布该帖子已解决,但找不到。感谢您的帮助!