C 程序输出延后?

发布于 2022-09-02 12:10:44 字数 3308 浏览 19 评论 0

为什么我写的程序会出现输出延后?
输入情况
如图,我是按照左边网页上的输入样例输入的,根据我的程序,输入 8 后就应该出现 ‘here',可直到下一次输入时才出现,而且根据我的程序,输完 A 1 2 后就应该执行

printf("Element = %c, cl = %c, cr = %c\n", T[i].Element, cl, cr);

但是并没有执行。
也就是我的程序中的

 printf("here\n");
        for (i = 0; i < n; i++) {
            printf("i = %d, n = %d\n", i, n);
            scanf("%c %c %c\n", &T[i].Element, &cl, &cr);
            printf("Element = %c, cl = %c, cr = %c\n", T[i].Element, cl, cr);

整个的执行顺序都不一样,为什么会是这样呢?
我的每一次输入输出都会延后一个,这是怎么回事?
而且最后输完 8 个后,还需要多输几个字符才能开始运行程序,这是怎么回事,求大神指教:)

#include <stdio.h>
#include <string.h>
#define MaxTree 10
#define ElementType char
#define Tree int
#define Null -1

struct TreeNode
{
    ElementType Element;
    Tree        Left;
    Tree        Right;
} T1[MaxTree], T2[MaxTree];


Tree BuildTree(struct TreeNode T[]);
int Isomorphic(Tree R1, Tree R2);


int main()
{
    Tree R1, R2;
    R1 = BuildTree(T1);
    R2 = BuildTree(T2);
    printf("hr3\n");
    if (Isomorphic(R1, R2))
        printf("Yes\n");
    else
        printf("No\n");

    return 0;
}

Tree BuildTree(struct TreeNode T[])
{
    printf("hr1\n");
    int n, i;
    scanf("%d\n", &n);
    int check[n];
    char cl, cr;
    int Root = -1;
    if (n) {
        for (i = 0; i < n; i++) {
            check[i] = 0;
        }
        printf("here\n");
        for (i = 0; i < n; i++) {
            printf("i = %d, n = %d\n", i, n);
            scanf("%c %c %c\n", &T[i].Element, &cl, &cr);
            printf("Element = %c, cl = %c, cr = %c\n", T[i].Element, cl, cr);
            if (cl != '-') {
                T[i].Left = cl - '0';
                check[T[i].Left] = 1;
            }
            else
                T[i].Left = Null;
            if (cr != '-') {
                T[i].Right = cr - '0';
                check[T[i].Right] = 1;
            }
            else
                T[i].Right = Null;
        }
        for (i = 0; i < n; i++) {
            if (!check[i])
                break;
        }
        Root = i;
    }
    return Root;
}


int Isomorphic(Tree R1, Tree R2)
{
    printf("hr3\n");
    if ((R1 == Null) && (R2 == Null))
        return 1;
    if (((R1 == Null) && (R2 != Null)) || ((R1 != Null) && (R2 == Null)))
        return 0;
    if (T1[R1].Element != T2[R2].Element)
        return 0;
    if ((T1[R1].Left == Null) && (T2[R2].Left == Null)) {
        //printf("hr3\n");
        return Isomorphic(T1[R1].Right, T2[R2].Right);
    }
    if (((T1[R1].Left != Null) && (T2[R2].Left != Null)) && ((T1[T1[R1].Left].Element) == (T2[T2[R2].Left].Element))) {
        // no need to swap the left and the right
        //printf("hr4\n");
        return (Isomorphic(T1[R1].Left, T2[R2].Left) && Isomorphic(T1[R1].Right, T2[R2].Right));
    }
    else    { //need to swap the left and the right
        //printf("hr5\n");
        return (Isomorphic(T1[R1].Left, T2[R2].Right) && Isomorphic(T1[R1].Right, T2[R2].Left));
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静赏你的温柔 2022-09-09 12:10:44

这是因为题主在int scanf( const char* format, ... );函数中的格式参数format设置导致的。

Tree BuildTree(struct TreeNode T[])
{
    printf("hr1\n");
    int n, i;
    scanf("%d", &n);  // <-- (1)
    int check[n];
    char cl, cr;
    int Root = -1;
    if (n) {
        for (i = 0; i < n; i++) {
            check[i] = 0;
        }
        printf("here\n");
        for (i = 0; i < n; i++) {
            printf("i = %d, n = %d\n", i, n);
            scanf("%c %c %c\n", &T[i].Element, &cl, &cr);  // <-- (2)
            printf("Element = %c, cl = %c, cr = %c\n", T[i].Element, cl, cr);
            //...

题主可以做几个小测试:

  • (1)处的语句换成scanf("%d", &n);

  • (2)处的语句换成scanf(" %c %c %c\n", &T[i].Element, &cl, &cr);

  • (2)处的语句换成scanf("%c %c %c", &T[i].Element, &cl, &cr);

  • (2)处的语句换成scanf(" %c %c %c", &T[i].Element, &cl, &cr);

具体原因可以参考这里这里关于格式参数format设置的说明,下面引用比较重要的几点:

format: C string that contains a sequence of characters that control how characters extracted from the stream are treated:

  • Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).

  • Non-whitespace character, except format specifier (%): Any character that is not either a whitespace character (blank, newline or tab) or part of a format specifier (which begin with a % character) causes the function to read the next character from the stream, compare it to this non-whitespace character and if it matches, it is discarded and the function continues with the next character of format. If the character does not match, the function fails, returning and leaving subsequent characters of the stream unread.

  • Format specifiers: A sequence formed by an initial percentage sign (%) indicates a format specifier, which is used to specify the type and format of the data to be retrieved from the stream and stored into the locations pointed by the additional arguments.

All format specifiers other than [, c, and n consume and discard all leading whitespace characters (determined as if by calling isspace) before attempting to parse the input. These consumed characters do not count towards the specified maximum field width.

Because most conversion specifiers first consume all consecutive whitespace, code such as

std::scanf("%d", &a);
std::scanf("%d", &b);

will read two integers that are entered on different lines (second %d will consume the newline left over by the first) or on the same line, separated by spaces or tabs (second %d will consume the spaces or tabs).

The conversion specifiers that do not consume leading whitespace, such as %c, can be made to do so by using a whitespace character in the format string:

std::scanf("%d", &a);
std::scanf(" %c", &c); // ignore the endline after %d, then read a char
挽心 2022-09-09 12:10:44

语句确实执行了,不过stdoutstdin有可能被系统缓冲区缓存,导致终端上显示的顺序不对应了。OJ本身一般是用重定向评测的,不受影响。你自己测试的时候也可以把输入放到file.in里,然后./tree < file.in

某些情况下,这样不方便调试,这时可以考虑用fflush()清空缓冲区。在我的系统中试了一下,如果不在printf("hr1\n");后面加fflush(stdout);,甚至程序一开始都不会显示hr1的,直接等待输入了…

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文