如果您将长行拆分为多行,如任务描述中所述,则在遇到剪切阈值时必须打印'\n' 而不是','。
在您知道该字符应该打印在当前行还是下一行之前,您不应该在输出流上打印该字符。因此,您必须存储所有字符,直到您知道它必须打印在哪一行。
您可能希望使用函数isblank 来确定字符是空格还是制表符。
按照community guidelines on homework questions,我暂时不会提供完整的问题解决方案。但是,如果需要,我会提供进一步的提示。
更新 1:
您最近一次编辑中的代码不正确。根据任务描述,您应该在阈值之前的最后一个空白处拆分行,而不是在阈值之后的第一个空白处。
大多数时候当你遇到一个新字符时,你无法知道它是属于当前行还是新行。因此,正如我在回答中已经说过的,您必须记住所有字符,直到您知道它们属于哪一行。在你知道它属于当前行还是下一行之前,你不应该打印一个字符。
如果您使用fgets 而不是getchar,您可能会发现更容易解决此问题。不过这个问题也可以用getchar解决。
更新 2:
由于您似乎已经为这个问题苦苦挣扎了好几天,我现在提供解决问题的方法:
这是我使用getchar的解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <assert.h>
#define CUT 10
int main( void )
{
//this memory buffer will hold the remembered
//line contents
char line[CUT+1];
//current index
int i = 0;
//whether a blank character has been encountered in
//the current line
bool found_blank = false;
//index of the last encountered blank character
int blank_index;
//this will store the current character
int c;
//this loop will read one character per loop iteration
while ( (c=getchar()) != EOF )
{
//if we encounter the end of the line, flush the
//buffer and start a new line
if ( c == '\n' )
{
line[i] = '\0';
puts( line );
i = 0;
found_blank = false;
continue;
}
//check if new character is blank and, if it is, then
//remember the index
if ( isblank(c) )
{
blank_index = i;
found_blank = true;
}
//write new character into array
line[i] = c;
if ( i == CUT - 1 )
{
if ( !found_blank )
{
//flush buffer
line[CUT] = '\0';
puts( line );
//reset line
i = 0;
found_blank = false;
continue;
}
else // found_blank == true
{
//remember character that is going to be overwritten
char temp = line[blank_index+1];
//output everything up to and including the last blank
line[blank_index+1] = '\0';
puts( line );
//move unwritten characters to start of next line
i = CUT - 1 - blank_index;
line[0] = temp;
memmove( line + 1, line+blank_index+2, i );
found_blank = false;
continue;
}
}
i++;
}
//check stream for error
if ( ferror(stdin) )
{
fprintf( stderr, "error reading input!\n" );
exit( EXIT_FAILURE );
}
//if we reach this, then we must have encountered
//end-of-file
assert( feof( stdin ) );
//flush buffer
line[i] = '\0';
puts( line );
}
这是我使用fgets的解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <assert.h>
#define CUT 10
int main( void )
{
char line[CUT+2];
size_t leftovers = 0;
//in every iteration of the loop, we write one line of output
for (;;)
{
size_t blank_index;
bool found_blank = false;
if ( fgets( line + leftovers, sizeof line - leftovers, stdin ) == NULL )
{
//print all leftovers
line[leftovers] = '\0';
printf( "%s\n", line );
break;
}
size_t len = strlen( line );
//this check is probably not necessary
assert( len != 0 );
if ( line[len-1] == '\n' )
{
//we read a complete line, so print it
printf( "%s", line );
leftovers = 0;
continue;
}
//if we reach this, then input line was not read in
//completely, or we are dealing with the last line before
//end-of-file or input failure
//find last blank
for ( size_t i = 0; line[i] != '\0'; i++ )
{
if ( isblank( (unsigned char)line[i] ) )
{
found_blank = true;
blank_index = i;
}
}
if ( !found_blank )
{
if ( len <= CUT )
{
if ( ferror(stdin) )
{
fprintf( stderr, "error reading input!\n" );
exit( EXIT_FAILURE );
}
//we should only reach this if end-of-file was
//encountered in the middle of a line
assert( feof(stdin) );
printf( "%s\n", line );
break;
}
//remember last character
char temp = line[len-1];
line[len-1] = '\n';
printf( "%s", line );
line[0] = temp;
leftovers = 1;
}
else
{
//remember character after last blank
char temp = line[blank_index+1];
//replace character after last blank with terminator
line[blank_index+1] = '\0';
//print line up to and including last blank
printf( "%s\n", line );
if ( temp != '\0' )
{
//move unprinted characters to start of next line
line[0] = temp;
leftovers = len - blank_index - 1;
memmove( line + 1, line + blank_index + 2, leftovers - 1);
}
else
{
leftovers = 0;
}
}
}
}
看来我最初使用fgets 而不是getchar 的建议不是很好,因为fgets 解决方案比getchar 解决方案稍微复杂一些。
这是两个程序的一些示例输入和输出(两个程序的行为方式相同):
示例输入:
This is a line with several words.
Thisisalinewithonelongword.
示例输出:
This is a
line with
several
words.
Thisisalin
ewithonelo
ngword.