如何在我的程序结束时一直输出我的结果,而不是在每次迭代结束时输出我的结果? (先前查询的更新版本)
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 或专用函数中完成。
所以我的程序接受一个字符串,然后将它作为选取框输出。我有一个 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 或专用函数中完成。