线条在c程序中消失

时间:2015-05-29 20:34:51

标签: c

我一直试图弄清楚这一点,并且没有在网上找到任何有关此行为的信息。我认为它是C语言特有的东西,所以我把它放在这里试图了解它是什么。当以下函数将其名称更改为main并编译并自行运行时,它正是我正在寻找的内容:

void print_to_screen(void) {
    system("clear");
    char *usor;
    usor = malloc(9 * sizeof(char));
    if(sizeof(getenv("USER")) > 8)
        return;
    usor = getenv("USER");

    FILE *inFile;
    char buf[BUFSIZ];
    char fileIn[30];
    sprintf(fileIn, "/home/%s/output3", usor);

    if((inFile = fopen(fileIn, "r")) == NULL) {
        perror(fileIn);
        return;
    }

    int lines = 0;
    int count = 0;
    int i = 0;
    while(fgets(buf, BUFSIZ, inFile) != NULL)
            lines++;
    if(lines == 0) {
        printf("Sortact empty. Press enter.");
        getchar();
        return;
    }
    rewind(inFile);

    for(i = 0; i <= PAGE; i++) {
        if(count == 0) {
            printf("%d accounts worked\n", lines);
            //sleep(2);
            printf("    %-8s %-8s  %8s   %8s  %8s  %8s\n", "begin", "end", "msg #", "activity", "response", "next_act");
            //sleep(2);
        }

        if(lines == count) {
            printf("End of output.  Press enter.");
            fclose(inFile);
            getchar();
            return;
        }
        fgets(buf, BUFSIZ, inFile);
        count++;
        printf("%3d %s", count, buf);

    }

    while(fgets(buf, BUFSIZ, inFile) != NULL) { 
        printf("q) to quit, Enter) for line-by-line feed, 'b') backup, *) next page\n");

        char c = getchar();
        if(c == 'b') {
                if(count == PAGE)
                    continue;
                system("clear");
                count -= 2;
                rewind(inFile);
                for(i = count; i > 0; i--) {
                    fgets(buf, BUFSIZ, inFile);
                    printf("%3d %s", count, buf);
                }
                continue;
        }
        else if(c == '\n') {
            if(lines == count) {
                    printf("End of output.  Press enter.");
                    fclose(inFile);
                    getchar();
                    return;
            }
            system("clear");
            count++;
            rewind(inFile);
            i = count;
            count = 0;
            for(; i > 0; i--) {
                fgets(buf, BUFSIZ, inFile);
                count++;
                printf("%3d %s", count, buf);       
            }
            continue;
        }
        else if(c == 'q') {
                return;
        }
        else {
            if(lines == count) {
                    printf("End of output.  Press enter.");
                    fclose(inFile);
                    getchar();
                    return;
            }
            system("clear");

            for(i = 0; i <= PAGE; i++) {
                if(lines == count) {
                    printf("End of output.  Press enter.");
                    fclose(inFile);
                    getchar();
                    return;
                }
                fgets(buf,BUFSIZ, inFile);
                count++;
                printf("%3d %s", count, buf);
            }
            continue;
        }
    }
    fclose(inFile);
}

但是,当我作为一个单独的函数从以下switch语句运行时,它会切断前两行输出(工作帐户和标题行):

while(c == 0) {
        printf("1) print to the screen, most recent first\n");
        printf("2) print to the screen, least recent first\n");
        printf("3) print to paper\n");
        printf("4) cancel\n");
        c = getchar();
        switch(c) {
            case '1' :
                sprintf(sort_c, "sort -r -k1.1,1.2 -k1.4,1.5 -k1.7,1.8 /home/%s/output2 > /home/%s/output3", usor, usor);
                free(usor);
                system(sort_c);
                print_to_screen();
                return 0;
            case '2' :
                sprintf(sort_c, "sort -k1.1,1.2 -k1.4,1.5 -k1.7,1.8 /home/%s/output2 > /home/%s/output3", usor, usor);
                free(usor);
                system(sort_c);
                print_to_screen();
                return 0;
            case '3' :
                sprintf(sort_c, "sort -k1.1,1.2 -k1.4,1.5 -k1.7,1.8 /home/%s/output2 > /home/%s/output3", usor, usor);
                system(sort_c);
                sprintf(print_c, "qprt -Plp3 /home/%s/output3", usor);
                system(print_c);
                free(usor);
                return 0;
            case '4' :
                free(usor);
                return 0;
            default :
                c = 0;
                system("clear");
                break;
        }
    }

我尝试删除循环以及大约十亿个其他内容,但没有任何帮助这种行为。前两行最初是在他们现在所处的循环之前。那些注释掉的sleep()语句告诉我这些行都被打印 - 一个然后另一个 - 然后它们被清除了。如果有人能帮我理解发生的事情,我将不胜感激。

由于

(哦,这是一个更大的程序的一部分,“usor”变量将被检查。我知道如果我不添加这个哈哈,我可能会陷入地狱。)

预期的输出是:

  

46个帐户有效       开始结束消息#活动响应next_act 1 12:44:29 13:04:19 0012497389 CR CS 2   08:40:28 08:54:40 0012498082 ZZ ZZ ZZ 3   08:40:06 08:40:22 0012500689 ZZ ZZ ZZ 4   08:39:47 08:39:59 0011906009 ZZ ZZ ZZ 5   08:39:31 08:39:43 0012199860 ZZ ZZ ZZ 6   08:39:04 08:39:27 0012499803 ZZ ZZ ZZ 7   08:37:58 08:38:50 0012514625 ZZ ZZ ZZ 8   08:37:18 08:37:55 0012224477 ZZ ZZ ZZ 9   08:37:03 08:37:15 0012169778 ZZ ZZ ZZ 10   08:36:20 08:36:59 0012499231 ZZ ZZ ZZ 11   08:36:06 08:36:17 0012501138 ZZ ZZ ZZ 12   08:34:58 08:36:00 0012206191 ZZ ZZ ZZ 13   08:34:20 08:34:51 0012349829 ZZ ZZ ZZ 14   08:31:59 08:34:11 0012348605 ZZ ZZ ZZ 15   08:31:22 08:31:54 0012431227 ZZ ZZ ZZ 16   08:30:12 08:31:04 0012425863 ZZ ZZ ZZ 17   08:29:13 08:30:02 0012420569 CR DS 18   08:07:07 08:29:07 0012414680 ZZ ZZ ZZ 19   08:06:42 08:07:01 0012414680 CR DS 20   08:06:28 08:06:37 0012185000 ZZ ZZ ZZ 21   08:05:26 08:05:49 0012206880 ZZ ZZ ZZ 22   08:04:23 08:05:22 0011775414 ZZ ZZ ZZ q)来   退出,输入)用于逐行馈送,'b')备份,*)下一页

当它作为自己的程序运行时,我得到的是什么。这就是我没有它的原因:

  

12:44:29 13:04:19 0012497389 CR CS 2   08:40:28 08:54:40 0012498082 ZZ ZZ ZZ 3   08:40:06 08:40:22 0012500689 ZZ ZZ ZZ 4   08:39:47 08:39:59 0011906009 ZZ ZZ ZZ 5   08:39:31 08:39:43 0012199860 ZZ ZZ ZZ 6   08:39:04 08:39:27 0012499803 ZZ ZZ ZZ 7   08:37:58 08:38:50 0012514625 ZZ ZZ ZZ 8   08:37:18 08:37:55 0012224477 ZZ ZZ ZZ 9   08:37:03 08:37:15 0012169778 ZZ ZZ ZZ 10   08:36:20 08:36:59 0012499231 ZZ ZZ ZZ 11   08:36:06 08:36:17 0012501138 ZZ ZZ ZZ 12   08:34:58 08:36:00 0012206191 ZZ ZZ ZZ 13   08:34:20 08:34:51 0012349829 ZZ ZZ ZZ 14   08:31:59 08:34:11 0012348605 ZZ ZZ ZZ 15   08:31:22 08:31:54 0012431227 ZZ ZZ ZZ 16   08:30:12 08:31:04 0012425863 ZZ ZZ ZZ 17   08:29:13 08:30:02 0012420569 CR DS 18   08:07:07 08:29:07 0012414680 ZZ ZZ ZZ 19   08:06:42 08:07:01 0012414680 CR DS 20   08:06:28 08:06:37 0012185000 ZZ ZZ ZZ 21   08:05:26 08:05:49 0012206880 ZZ ZZ ZZ 22   08:04:23 08:05:22 0011775414 ZZ ZZ ZZ q)来   退出,输入)用于逐行馈送,'b')备份,*)下一页

是的,我已经通过gdb运行了很多次,并没有告诉我屏幕是如何清除的。

1 个答案:

答案 0 :(得分:3)

我自己尝试编译代码。当您输入1或2作为主程序的输入时,c = getchar();(主,第6行)仅消耗第一个字符,留下&#39; \ n&#39;在stdin中,第54行的print_to_screen中的getchar会立即使用它。这会导致system("clear")被调用(print_to_screen,第74行),清除标题行,再次打印{{1}行。没有标题,这看起来好像标题消失了。如果运行output3作为主函数,则不会发生这种情况,因为运行时stdin中没有额外的输入。

您可以进行最简单的修改,即在print_to_screen(主要,第6行)之后添加getchar();,以删除额外的&#39; \ n&#39;来自stdin。但最好使用c = getchar();代替fgets,以便一次读取整行。

通常建议使用getchar代替snprintf(以避免缓冲区溢出),sprintf而不是calloc(以避免整数溢出),以及始终检查分配的返回值和malloc。由于潜在的命令注入,用户提供的输入的fgets调用当然非常敏感(虽然我知道你说输入是安全的)。有关详细信息,请参阅sprintf(3)malloc(3)中的CAVEATS。