如何在我的程序结束时一直输出我的结果,而不是在每次迭代结束时输出我的结果? (先前查询的更新版本)

How to output my results all the way at the end of my program versus at the end of each iteration? (Updated version of previous query)

所以我的程序接受一个字符串,然后将它作为选取框输出。我有一个 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] = '[=12=]';

        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;
}

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

#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] = '[=13=]';

            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;
}

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

你的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] = '[=12=]';
    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;
}

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

首先是恕我直言,这是更好的方法,因为要存储的数据量更少。 OTOH 正在存储输出,这是并行化获取输入和生成输出的良好开端。我选择后者,因为这更接近您问题中的措辞。

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

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);

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


整体代码草图:

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 或专用函数中完成。