[英]Separating words by taking input from user in C
系统会为您提供一行文字,长度最多为1000个字符。 文本由英语单词组成。 行中的相邻单词由单个空格分隔。
第二行由单个整数“ N”组成,表示输出线的宽度。
以以下格式打印输入文本:
O SOFT embalmer of the still midnight Shutting with careful fingers
34
O SOFT embalmer of the still
midnight Shutting with careful
fingers
每个输出行最多为34个字符长。 “午夜”不适用于第一行,因此已移至第二行。 “手指”不适用于第二行,因此已移至第三行。
#include<stdio.h>
void main()
{
int n,i,c;
char arr[1000];
scanf("%d",&n);
//input
while((c=getchar())!=EOF)
{
arr[i]=c;
i++;
}
//checking
while(i!=n)
{
printf("%c",arr[i]);
i++;
}
printf("\n");
}
我的代码给出了无限循环,没有给出输出。
我想通过但我失败的示例测试用例。
Input
Imagination is more powerful than knowledge
14
OUTPUT
Imagination is\n
more powerful\n
than \n
knowledge
谁能帮帮我吗。
几个问题:在阅读第一行之前,您正在读取长度(在第二行)。 那是行不通的-当scanf()在“ Imagination”中看到“ I”并且没有设置n并将其保留为未定义的值时,它将失败。
另外,while循环仅在EOF处终止,而不在\\ n处终止,因此您也将阅读第二行。
最后,您永远不会初始化i,因此不能保证您开始在索引0处写arr []。
如果在编译时打开了-Wall -Werror,则编译器(假设您正在使用gcc)会为您标记出最后一个错误。 从长远来看,打开所有可能的错误检查(并使警告被视为错误)将为您节省很多麻烦。
您必须先输入字符串,然后输入int并使用strtok()
函数将字符串断开。
#include <stdio.h>
#include <string.h>
int main (void)
{
int n,i=0,count=0,len;
char arr[1000];
char *token;
fgets(arr, sizeof(arr), stdin);
scanf("%d",&n);
//checking
token = strtok(arr, " ");
while (token != NULL)
{
len=strlen(token);
count+=len;
if(count<n)
{
printf("%s ", token);
count++;
}
else if(count==n)
{
printf("%s", token);
printf("\n ");
count=1;
}
else
{
printf("\n%s ", token);
count=len+1;
}
token = strtok(NULL, " ");
}
return 0;
}
像这样:
#include <stdio.h>
#include <string.h>
int main(void){
char arr[1000+2];//+2: newline + NUL
fgets(arr, sizeof arr, stdin);
int N;
if(scanf("%d", &N) != 1 || N <= 0){
fputs("invalid input\n", stderr);
return -1;
}
char *p = arr;
size_t output_len = 0;
while(*p){
size_t word_len = strcspn(p, " \n");
if(!word_len){
break;
} else if(!!output_len + output_len + word_len <= N){// <= N: exclude newline, if include newline Change <= to <
if(!!output_len){
putchar(' ');
++output_len;
}
printf("%.*s", (int)word_len, p);
output_len += word_len;
p += word_len + 1;//+ 1: skip space or newline
} else {
puts("");
output_len = 0;
}
}
puts("");
}
要完善答案集,您可以简单地使用滑动窗口来跟踪适合给定换行长度的单词。
例如,将sp
用作起始指针指向一行中单词的第一个字符,将ep
用作结尾指针指向所遇到的最后一个空格,则可以执行以下操作:
#include <stdio.h>
#define MAXC 1000
int main (void) {
char buf[MAXC+2] = "", /* good job BLUEPIXY */
*p = buf, /* pointer to current char */
*sp = buf, /* pointer to start of line to print */
*ep = buf; /* pointer to end of line to print */
int n = 0;
/* read/validate line using fgets for line-oriented input */
if (!fgets (buf, MAXC, stdin) || *buf == '\n') {
fprintf (stderr, "error: EOF or empty string\n");
return 1;
}
/* read/validate n */
if (scanf ("%d", &n) != 1) {
fprintf (stderr, "error: invalid conversion for 'n'\n");
return 1;
}
for (; *p && *p != '\n'; p++) { /* loop over each char (omit '\n')*/
if (*p == ' ') /* if space, set ep */
ep = p;
if (p - sp >= n) { /* if limit from start reached */
while (sp < ep) /* loop over chars sp -> ep */
putchar (*sp++);
putchar ('\n'); /* tidy up with '\n' */
sp = ++ep; /* set start to next after end */
ep = ++p; /* set end to next after current */
}
}
while (*sp && *sp != '\n') /* output last line of chars */
putchar (*sp++);
putchar ('\n');
return 0;
}
不管您怎么做,只要您考虑了自上次适合该行以来的字符,就可以了。
编程成功有两个关键因素(别名为“用更少的精力就能更快地获得工作程序”和“在聚会上玩得开心而不是花 功夫 去做” )
给变量n,i
命名会导致不必要的认知负担(您必须记住它们的含义)。 我知道在教学C语言时使用一个字母和/或一个隐秘的名称(或不关心它)是一种悠久的传统,但这是一种愚蠢且适得其反的做法。
在问题空间中,您有类似
我建议您将变量重命名为word_length
, current_line_width
, max_line_width
。 您将很快看到代码的问题。
同样,将某些关注点分离可能会有所帮助。 为指定的行宽设置给定的文本字符串格式是一项明确的任务,那么为什么不编写一个函数并从main调用它呢?
int main()
{
char *test_string = "This is a very long string for my first test";
format_string(test_string, 10);
return 0;
}
关于另一个主题:有两种通常的方法可以解决此问题。
编辑:在这里
void format_string(char string[], int max_width)
{
char *position = string;
int line_length = 0;
for(;;) { // a loop over words
// get a word
while(*position == ' ') {
position++; // skip spaces
}
if (*position == '\0') {
break; // no more words -> break
}
// found one !
char *word_start = position;
while((*position != ' ') && (*position) != '\0') {
position++;
}
char *word_end = position;
int word_length = word_end - word_start;
// skip to next line if needed
// a word longer than max_width will
// be printed alone beyond the right margin
int new_width = line_length + word_length + 1;
if ((line_length != 0)
&& ( new_width > max_width)) {
printf("\n");
line_length = 0;
}
// add space between words if needed
if (line_length != 0) {
printf(" ");
line_length++;
}
// put word
for (char *p = word_start; p != word_end; p++) {
printf("%c", *p);
line_length++;
}
}
printf("\n");
}
请记住,程序员的任务不是编写可以正常工作的可执行程序。 这是一个目标,但是,日常工作是花时间编写/维护稍后将要工作的源代码,完成时将其删除,删除所有错误等,并进行修改以供以后使用等。
因此,请尝试编写清晰的代码,当您必须阅读时,这些代码看起来绝对是显而易见的。 您是在尝试使其正常运行时必须多次阅读的人。
它不会在第34位保留空格-我不确定是否需要。 其他答案也无法保留。
#include<stdio.h>
#include<string.h>
void main() {
int n, i = 0, c;
char arr[1000], *p, *q;
//input
while((c = getchar()) != '\n')
arr[i++] = c;
scanf("%d", &n);
i = 0;
q = arr;
//checking
p = strchr(q, ' ');
while (p) {
while (p - q + i < n) {
p[0] = 0;
printf("%s ", q);
i += p - q + 1;
q = p + 1;
p = strchr(q, ' ');
if (p == 0) break;
}
i = 0;
puts("");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.