简体   繁体   English

用空格替换换行符并按特定行长对单词进行排序

[英]Replacing newlines with spaces and sorting words in a specific lines length

I just opened a text file that contains several lines with different lengths, some lines start with a "." 我刚刚打开了一个文本文件,其中包含几行不同长度的行,有些行以“。”开头。 (dot) so those are defined as functions and i'll deal with them later. (点),因此将它们定义为函数,稍后再处理。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
int main()
{       
char line[10000];
char filename[30]; 
FILE *fp;
int i;
int u;

printf("Enter file name with extension\n");
gets(filename);

fp = fopen(filename,"r");

if( fp == NULL )
{
    perror("Error while opening the file.\n");
    exit(EXIT_FAILURE);
}

I tried hard for 2 days to print the rest of the lines (not functions) in the same line but when I used the strtok function as you can see, it removed it without adding a space, so the characters from different lines mixed. 我努力尝试了两天,以便在同一行中打印其余的行(不是函数),但是当您使用strtok函数时,如您所见,它删除了它而没有添加空格,因此来自不同行的字符混合在一起了。

The second problem is I'm trying to limit line lengths to max of 60 characters, and fit the words into the spaces if the length is equal or less. 第二个问题是我试图将行长度限制为最多60个字符,并且如果长度等于或小于该长度,则将单词适合空格。

while(fgets(line,10000,fp) != NULL )
{       
    if(line[0]!='.'){ 
        strtok(line,"\n");
        for(u=0;u<strlen(line);u++){
            if(u==60){  
                printf("\n");
            }
            else{printf("%c",line[u]);}
        }   

        printf("%s",line);
    }
    else{printf("");}

}

fclose(fp);
return 0;
}

You need an algorithm similar to: 您需要一种类似于以下内容的算法:

  • set output line empty and line length to zero 将输出行设置为空并将行长设置为零
  • while read input line does not detect EOF 而读取输入行未检测到EOF
    • if it is a function line, continue with next iteration of while read loop 如果是功能行,则继续进行while读取循环的下一次迭代
    • while not at end of current input line 而不在当前输入行的末尾
      • find next word in input line ( strtok() perhaps, or strcspn() or strpbrk() ) 在输入行中找到下一个单词strtok()也许是strtok()strcspn()strpbrk()
      • if length of output line plus 1 for a space plus length of next word is bigger than 60, print output line, set line length to zero 如果输出行的长度加一个空格的空格加上下一个单词的长度大于60,则打印输出行,将行长设置为零
      • if line length greater than zero, add space 如果线长大于零,请添加空间
      • add next word to output line and increment length 向输出行添加下一个单词并增加长度
  • if there is anything in the output line, print it 如果输出行中有任何内容,请打印出来

This has you ignoring function lines. 这使您忽略了功能线。 Alternatively, you can flush the current output line (if it is not empty), print the function line, and go for the next line. 或者,您可以刷新当前输出行(如果不为空),打印功能行,然后转到下一行。

Note that if the next word is 60 characters or longer, this will not truncate it, or split it; 请注意,如果下一个单词是60个字符或更长,则不会截断或拆分它; it will just occupy a line on its own. 它只会自己占据一条线。 The onus is on you to be careful that there is no buffer overflow. 注意,缓冲区没有溢出是您的责任。 For example, you might flush the previous output line, print this word and its newline, and then reset the output to empty. 例如,您可以刷新上一个输出行,打印该单词及其换行符,然后将输出重置为空。 Or you might split the word (but would you split some of it to fit on the current line and the rest on the next line, or just force the start onto the next line and then split?). 或者,您可以拆分单词(但是您会拆分其中的一部分以适合当前行,其余拆分为下一行,还是只是将起始点强制到下一行然后拆分?)。 And what if the word is 250 characters long? 如果单词长度为250个字符怎么办?


This is a fairly direct transliteration of the algorithm above. 这是上述算法的相当直接的音译。 It reads from standard input; 它从标准输入读取; I decline to answer prompts about which file name to open. 我拒绝回答有关打开哪个文件名的提示。 If I want to handle arbitrary files, they'll be passed on the command line as arguments. 如果我要处理任意文件,它们将在命令行中作为参数传递。

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

/*
.function line should not appear in output
*/

/*
WordOfMoreThanSixtyCharacters--WithNaryASpaceInSight--ThoughThereIsPunctuation!
*/

enum { OUT_LENGTH = 60 };

int main(void)
{
    char oline[OUT_LENGTH]; // output line
    char iline[4096];       // input line
    int  olength = 0;       // length of data in output line
    const char separators[] = " \n\t";

    while (fgets(iline, sizeof(iline), stdin) != 0)
    {
        if (iline[0] == '.')
            continue;
        int wlength;            // word length
        char *wline = iline;    // start of word
        wline += strspn(wline, separators);
        while ((wlength = strcspn(wline, separators)) > 0)
        {
            if (olength + 1 + wlength > OUT_LENGTH)
            {
                printf("%.*s\n", olength, oline);
                olength = 0;
                if (wlength >= OUT_LENGTH)
                {
                    printf("%.*s\n", wlength, wline);
                    wline += wlength;
                    wlength = 0;
                }
            }
            if (wlength > 0)
            {
                if (olength > 0)
                    oline[olength++] = ' ';
                strncpy(&oline[olength], wline, wlength);
                olength += wlength;
                wline += wlength;
            }
            wline += strspn(wline, separators);
        }
    }
    if (olength > 0)
        printf("%.*s\n", olength, oline);
    return 0;
}

Output when run on its own source code: 在其自身的源代码上运行时的输出:

#include <stdio.h> #include <string.h> /* */ /*
WordOfMoreThanSixtyCharacters--WithNaryASpaceInSight--ThoughThereIsPunctuation!
*/ enum { OUT_LENGTH = 60 }; int main(void) { char
oline[OUT_LENGTH]; // output line char iline[4096]; // input
line int olength = 0; // length of data in output line const
char separators[] = " \n\t"; while (fgets(iline,
sizeof(iline), stdin) != 0) { if (iline[0] == '.') continue;
int wlength; // word length char *wline = iline; // start of
word wline += strspn(wline, separators); while ((wlength =
strcspn(wline, separators)) > 0) { if (olength + 1 + wlength
> OUT_LENGTH) { printf("%.*s\n", olength, oline); olength =
0; if (wlength >= OUT_LENGTH) { printf("%.*s\n", wlength,
wline); wline += wlength; wlength = 0; } } if (wlength > 0)
{ if (olength > 0) oline[olength++] = ' ';
strncpy(&oline[olength], wline, wlength); olength +=
wlength; wline += wlength; } wline += strspn(wline,
separators); } } if (olength > 0) printf("%.*s\n", olength,
oline); return 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM