如何在程序结束时和每次迭代结束时一直输出结果? (以前查询的更新版本)

时间:2016-02-28 07:25:10

标签: c function output marquee

所以我的程序接受一个字符串,然后将其输出为选框标记。我有一个for循环,因此它可能需要多个字符串,然后输出每个字符串作为符号。

我的问题是:每次迭代后,它会输出符号,然后继续提示我输入下一个字符串,当我希望它立即接收所有输入时,然后在最后输出每个符号。这就是我所说的:

Current Input:
3
Hello World!
5
Sign #1: (This is the output)
[Hello]
[ello ]
[llo W]
[lo Wo]
[o Wor]
[ Worl]
[World]
[orld!]
[rld! ]
[ld! H]
[d! He]
[! Hel]
[ Hell]
Activist
10
Sign #2: (This is the output)
[Activist  ]
LOL
2
Sign #3: (This is the output)
[LO]
[OL]
[L ]
[ L]

这就是我想要的:

Input:
3
Hello World!
5
Activist
10
LOL
2 
Output:
Sign #1: 
[Hello]
[ello ]
[llo W]
[lo Wo]
[o Wor]
[ Worl]
[World]
[orld!]
[rld! ]
[ld! H]
[d! He]
[! Hel]
[ Hell]

Sign #2:
[Activist  ]

Sign #3:
[LO]
[OL]
[L ]
[ L]

这是我的原始代码:

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

void ignoreRestOfLine(FILE *fp) {
    int c;
    while ((c = fgetc(fp)) != EOF && c != '\n');
}

int main() {
    int num_times, count = 0;
    int marq_length, sign = 0;
    scanf("%d ", &num_times);
    char s[100];

    for (count = 0; count < num_times; count++) {
        if (fgets(s, sizeof(s), stdin) == NULL) {
            // Deal with error.
        }
        if (scanf("%d", &marq_length) != 1) {
            // Deal with error.
        }
        ignoreRestOfLine(stdin);

        size_t n = strlen(s) - 1;
        int i, j;

        if (s[strlen(s)-1] == '\n')
            s[strlen(s)-1] = '\0';

        printf("Sign #%d:\n", ++sign);

        if (n <= marq_length) {
            printf("[%-*s]\n", marq_length, s);
        } else {
            for (i = 0; i < n + 1; i++) {
                putchar('[');
                for (j = 0; j < marq_length; j++) {
                    char c = s[(i + j) % (n + 1)];
                    if (!c)
                        c = ' ';
                    putchar(c);
                }
                printf("]\n");
            }
        }
    }
    return 0;
}

这是我的UPDATED代码,我在其中添加了我的代码部分,它实际上将字符串输入到一个函数中。我只是不知道如何正确地将其调回主函数,以便它可以在最后输出所有符号:

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

void ignoreRestOfLine(FILE* fp){
   int c;
   while ( (c = fgetc(fp)) != EOF && c != '\n');
}

char getSign(char s[100], int marq_length);
char getSign(char s[100], int marq_length){

    int count =0;
    int sign =0;
    //char s[100];
    if ( fgets(s, sizeof(s), stdin) == NULL )
    {
       // Deal with error.
    }

    if ( scanf("%d", &marq_length) != 1 )
    {
       // Deal with error.
    }

    ignoreRestOfLine(stdin);

    size_t n = strlen(s)-1;
    int i,j;


        if(s[strlen(s)-1] == '\n')
            s[strlen(s)-1] = '\0';

            printf("Sign #%d:\n", ++sign);

    if (n <= marq_length) {
        printf("[%-*s]\n", marq_length, s);
    } else {
        for (i = 0; i < n + 1; i++) {
            putchar('[');
            for (j = 0; j < marq_length; j++) {
                char c = s[(i + j) % (n + 1)];
                if (!c)
                    c = ' ';
                putchar(c);
            }
            printf("]\n");
        }
    }
}

int main(){
    int i, num_times, sign_length;
    char string[100];
    scanf("%d", &num_times);
    //char *results=malloc(num_times * sizeof(char));
    for(i=0 ;i<num_times;i++){
        scanf("%s", string);
        scanf("%d", &sign_length);
        printf((getSign(string, sign_length)));
    }
    return 0;
}

2 个答案:

答案 0 :(得分:0)

我认为阅读所有输入然后打印结果是好的,因为输入很短,这些大小很容易预测。

您的main()功能应该是这样的

int main(void){
    int i, num_times, *sign_length;
    char (*string)[100];
    /* read number of test cases */
    scanf("%d", &num_times);
    /* allocate buffer to store input */
    sign_length = malloc(sizeof(*sign_length) * num_times);
    string = malloc(sizeof(*string) * num_times);
    if (sign_length == NULL || string == NULL) {
        free(sign_length);
        free(string);
        return 1;
    }
    /* read input */
    for(i=0 ;i<num_times;i++){
        scanf("%99s", string[i]);
        scanf("%d", &sign_length[i]);
    }
    /* process and print */
    for(i=0 ;i<num_times;i++){
        getSign(string[i], sign_length[i]);
    }
    /* cleanup */
    free(string);
    free(sign_length);
    return 0;
}

以及试图破坏getSign()

中输入的部分
    if ( fgets(s, sizeof(s), stdin) == NULL )
    {
       // Deal with error.
    }

    if ( scanf("%d", &marq_length) != 1 )
    {
       // Deal with error.
    }

    ignoreRestOfLine(stdin);

必须删除。

必须将

#include <stdlib.h>添加到代码的头部才能使用malloc()free()

更新:以下是修复了问题的程序。

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

void getSign(char s[100], int marq_length, int case_number);
void getSign(char s[100], int marq_length, int case_number){

    size_t n = strlen(s)-1;
    size_t i,j;
    if (strlen(s) < n) n = 0;

    if(s[n] == '\n')
        s[n] = '\0';
    else
        n++;

    printf("Sign #%d:\n", case_number);

    if (n <= (size_t)marq_length) {
        printf("[%-*s]\n", marq_length, s);
    } else {
        for (i = 0; i < n + 1; i++) {
            putchar('[');
            for (j = 0; j < (size_t)marq_length; j++) {
                char c = s[(i + j) % (n + 1)];
                if (!c)
                    c = ' ';
                putchar(c);
            }
            printf("]\n");
        }
    }
}

int main(void){
    int i, num_times, *sign_length;
    char (*string)[100];
    /* read number of test cases */
    if(scanf("%d", &num_times) != 1) return 1;
    /* allocate buffer to store input */
    sign_length = malloc(sizeof(*sign_length) * num_times);
    string = malloc(sizeof(*string) * num_times);
    if (sign_length == NULL || string == NULL) {
        free(sign_length);
        free(string);
        return 1;
    }
    /* read input */
    for(i=0 ;i<num_times;i++){
        int dummy;
        while((dummy = getchar()) != '\n' && dummy != EOF); /* skip rest of previous line */
        if(scanf("%99[^\n]%d", string[i], &sign_length[i]) != 2) {
            free(sign_length);
            free(string);
            return 1;
        }
    }
    /* process and print */
    for(i=0 ;i<num_times;i++){
        getSign(string[i], sign_length[i], i + 1);
    }
    /* cleanup */
    free(string);
    free(sign_length);
    return 0;
}

答案 1 :(得分:0)

我在这里采用的方法是存储输入,直到读取所有输入,然后才生成输出,或者存储输出并将其打印延迟到最后。

首先是恕我直言的意见更好的方法,因为存储的数据量较少。 OTOH存储输出是并行化输入和生成输出的良好第一步。我跟随后者一起去,因为这更接近你问题中的措辞。

好的,你的输出基本上是一个C字符串。因此,您需要为每个输入存储其中一个。幸运的是,你知道甚至在第一次迭代之前你会得到多少输入,所以你可以事先分配正确的空间量:

char const ** outputs; // A pointer to (an array of) constant C strings
outputs = malloc(sizeof(*outputs) * numInputs);

然后,您在执行此操作时读取输入并将输出生成为C字符串。你一直在使用堆栈分配(常量)缓冲区。为了能够在每次迭代中重用该缓冲区,您需要将结果复制出来:

char * result = malloc(strlen(sign) + 1);
strcpy(result, sign);

进入你的输出数组的商店:

outputs[currentIteration] = result;

最后,最后打印每个输出并在完成后释放已分配的内存:

for (size_t o = 0; o < numOutputs; ++o) {
  printf("%s\n", outputs[o]);
  free(outputs[o]);
}

最后,不要忘记释放已为输出分配的数组:

free(outputs);

注意:您应该检查每个分配是否成功。此外,使用一个恒定大小的缓冲区(在堆栈上)是OK 只有你绝对确定这个缓冲区永远不会溢出!您应该尝试将上述内容和(小)函数中的符号生成包装起来。

整体代码草图:

int main() {
  // read how many inputs you'll get
  // allocate outputs
  // iterate, so that for each input:
    // you read the input
    // generate the sign
    // copy the result into the outputs array
  // iterate over all outputs
    // print output
    // free allocated memory of that output
  // free memory for outputs
}

读取输入并生成符号应该在两个不同的函数中完成(因此既不是原始函数也不是更新的代码)。基本上我认为拥有这些函数应该会给你一个合理的代码结构:

// Read both the string and length, allocating memory for the string
bool read_input(char **string, unsigned * marq_length);
// Could alternatively be done with a fixed buffer
bool read_input(char * string, size_t max_string_size, unsigned * marq_length);

// Note: for bool include stdbool, or use a char instead

一个生成标志:

// Store the result in the fixed size buffer at dest, check for overflow!
void generate_sign(char * dest, size_t max_dest_size, char const * input, unsigned marq_length);

打印输出的事情可以直接在main或专用函数中完成。