【问题标题】:calling system() from c从 c 调用 system()
【发布时间】:2013-08-20 11:09:24
【问题描述】:

我试图从 c 执行系统调用。执行以下代码时,首先打印日期,然后在新行上打印" Todays date is ..........:"。当我用 puts 替换 printf 时,它按我的意图执行。(objdump 显示 puts@plt 代替了第二个 printf)。谁能告诉我为什么会这样?

  #include <stdlib.h>

    int main() { printf(" Todays date is ..........:");

    system("/bin/date");
    printf("\n This is your exclusive shell\n");  
    system("/bin/sh");
    return 0; 
    }

提前致谢。

【问题讨论】:

    标签: c system


    【解决方案1】:

    printf() 将您的字符串放入缓冲区中,一旦您向下一行,它就会将其写入屏幕。这就是为什么当你这样做时

    printf(" Todays date is ..........:");
    
    system("/bin/date");
    

    您可能会先打印日期。

    stdout 流是缓冲的,因此只会在到达换行符后(或被告知时)显示缓冲区中的内容。您有几个选项可以立即打印:

    • 打印到stderr,而不是使用fprintf

      fprintf(stderr, "I will be printed immediately");
      
    • 在需要时刷新stdout 以使用fflush

      printf("Buffered, will be flushed");
      fflush(stdout); // Will now print everything in the stdout buffer
      
    • 或者您也可以使用setbuf 禁用stdout 上的缓冲:

      setbuf(stdout, NULL);
      

    【讨论】:

    • 假设如果 OP 在第一个 printf("Today......\n") 中添加 \n,那么他应该得到统一的行为,因为 \n 强制为 fflush。我说的对吗?
    • @GrijeshChauhan 它在我的系统上不起作用。但所有其他建议都有效
    • @user146297 感谢您的通知。尽管 NoIdeaForName 的回答完全清楚地说明了发生的事情以及如何解决。我认为\n fflush 是实现定义的,如果我得到任何链接,我会与你分享。
    • 这取决于流是完全缓冲的 (_IOFBF) 还是行缓冲的 (_IOLBF)。该标准没有说明标准输出的行为方式。但通常它在交互模式下默认设置为行缓冲(甚至无缓冲)。
    【解决方案2】:
    printf(" Todays date is ..........:");
    

    ==>

    printf(" Todays date is ..........:\n");
    

    或在printf 行之后添加fflush(stdout);

    【讨论】:

    • \n 总是在 C 中刷新 ? ,因为this post 说它没有
    • 我相信如果 stdout 连接到行缓冲终端,它会刷新,但它依赖于实现(和系统)。
    • @GrijeshChauhan 在行缓冲区中\n 刷新缓冲区。终端默认为行缓冲区
    • @LidongGuo 我过去也观察到。但它是 C 中定义明确的行为吗?
    • @GrijeshChauhan 不,它没有在 C 标准中指定。不过,它可以在 POSIX 中定义。这是其中一种情况,它主要取决于 stdout 的实际含义(我相信,“stdout”在托管环境中编译的 C 程序中被明确定义为 SOMETHING,但它可能是常规文件、终端或甚至网络 I/O 以及换行符 printf("foo\n") 是否刷新都超出了 C 标准的范围(无论如何它可能在 Unix、Windows 或 VMS 下做不同的事情)。
    【解决方案3】:

    printf 使用缓冲区。
    如果您想立即打印文本,您必须致电fflush

    printf(" Todays date is ..........:");
    fflush(stdout);
    system("/bin/date");
    

    【讨论】:

      【解决方案4】:
        #include <stdlib.h>  
        #include <stdio.h>
      
          int main() { printf(" Todays date is ..........:\n"); //add \n at the end. this is same behavior as puts. now date will print after this
      
          system("/bin/date");
          printf("\n This is your exclusive shell\n");  
          system("/bin/sh");
          return 0; 
          }  
      

      否则你可以在printf("Todays date is ....:"); 声明之后使用fflush(stdout);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 2016-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多