简体   繁体   中英

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.

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.

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
    • if it is a function line, continue with next iteration of while read loop
    • while not at end of current input line
      • find next word in input line ( strtok() perhaps, or strcspn() or 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
      • 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; 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?


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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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