簡體   English   中英

如何將數據傳遞給在Linux中調用scanf()和read()的程序

[英]How to pipe data to a program which calls scanf() and read() in Linux

我有一個C程序,看起來像這樣:

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

int main()
{
    int n;
    char str[16];
    scanf("%d", &n);
    printf("n: %d\n", n);

    int count = read(STDIN_FILENO, str, 16);
    printf("str: %s\n", str);
    printf("read %d bytes\n", count);
}

如果我使用類似命令將數據傳輸到此程序中

(echo -en '45\n'; echo -en 'text\n') | ./program

只有scanf()實際讀取數據。 read()只讀取0個字節。

換句話說,程序輸出

n: 45
str:
read 0 bytes

如何將數據傳輸到scanf()read()

編輯:對不起,我應該澄清:我正在尋找一種方法來做到這一點,而無需修改源代碼。 感謝那些回答和評論的人。

根本不建議對同一文件描述符使用文件描述符函數(讀取)和流函數(scanf)。 使用FILE * (即fread / fprintf / scanf / ...)的函數是緩沖數據,而使用文件描述符(即read/write/... )的函數不使用這些緩沖區。 在您的情況下,修復程序的最簡單方法是使用fread而不是read 該計划可能如下所示:

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

int main() {
  int n;
  char str[16];
  scanf("%d", &n);
  printf("n: %d\n", n);

  int count = fread(str, 16, 1, stdin);
  printf("str: %s\n", str);
  printf("read %d bytes\n", count);
}

在您的原始示例中, scanf已經讀取了前面的輸入並將其存儲在其緩沖區中。 因為輸入很短並且可以立即使用,所以它完全被讀取到緩沖區並且您的read調用沒有更多要閱讀。

直接從終端輸入輸入時不會發生這種情況,因為從終端設備讀取時, scanf不會將數據緩沖超過一行。 如果您通過命令在管道輸入中創建時間暫停,也不會發生這種情況:

(echo -en '45\n'; sleep 1; echo -en 'text\n') | ./program
#include <stdio.h>
#include <unistd.h>

int main()
{
    int n;
    char str[16];
    setbuf(stdin, NULL); // Ensure that there's no buffering for stdin
    scanf("%d", &n);
    printf("n: %d\n", n);

    int count = read(STDIN_FILENO, str, 16);
    printf("str: %s\n", str);
    printf("read %d bytes\n", count);
}

正如前面的答案所說,scanf引起了你的問題,因為它使用緩沖區。 因此,您可以通過調用setbuf(stdin,NULL)來確保它不會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM