Code căn lề dòng

Đây là source code của em. Giờ đang có một lỗi như này. Cứ phải có đủ ký tự một dòng thì nó mới căn, vấn đề là khi nhập 1 đoạn text thì thường có dòng cuối nó sẽ không đủ kì tự môt dòng( như em quy định là 50 trong code) thì khi đó nó se không in

#include <string.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#define MAX_WORD_LEN  20
#define MAX_LINE_LEN  50
int IsWhiteSpace(int );
int ReadWord(char *word ) ;
void AddWord(const char *word,char* , int* );
void WriteLine(const char *line,int lineLend ,int numWords);
void ClearLine(char *, int *lineLend,int *numWords);


int main() {
    char word[MAX_WORD_LEN+1];
    int wordLend = 0;
    char line[MAX_LINE_LEN +1];
    int lineLend = 0;
    int numWords = 0;
    //<xóa dòng>
    ClearLine(line,&lineLend,&numWords);
    for(; ;) {
        //<Đọc một từ>
        wordLend = ReadWord(word) ;
        //if(Hết từ)
        if (wordLend == 0) {
                            if (lineLend>0)
                            // in dòng đó ra và thoát
                            puts(line);
        return 0;
        }
            /*
            <Từ không vừa dòng hiện tại >
          <In dòng có căn phải>
           <Xóa dòng>
           */
        if((wordLend + 1 + lineLend) > MAX_LINE_LEN) {
            WriteLine(line,lineLend,numWords);
            ClearLine(line,&lineLend,&numWords);
            //fflush(stdin);
        }
         //<Thêm từ vào dòng>
        AddWord(word,line,&lineLend);
        numWords++;
    }
    return 0;
}
// đọc mọt từ
int ReadWord(char *word) {
    int ch; // nếu là char thì không kiểm tra được kí tự EOF = 255
    int pos = 0;

    /*
        + bỏ qua white_space
        + nếu đọc vào kí tự trăng ,tab nó sẽ bỏ qua để đọc kí tự tiếp theo ,xuống dòng
    */
    ch = getchar();
    while(IsWhiteSpace(ch))
        ch = getchar();
    /* Lưu các ký tự vào đến MAX_WORK_LEN. */
    while ((!IsWhiteSpace(ch))&&( ch != 'EOF')) {
        if( pos < MAX_WORD_LEN) {
            word[pos] = (char)ch ;
            pos++;
        }
        ch = getchar();
    }
    word[pos] = '\0';
    // trả vể độ dài từ
    return pos;
}
int IsWhiteSpace(int ch) {
    return (( ch == ' ' )||( ch == '\n')||( ch == '\t'));
}
void AddWord(const char *word, char *line, int *lineLend) {
    if(*lineLend > 0) {
        line[*lineLend] = ' ';
        line[*lineLend + 1] = '\0';
        (*lineLend)++;
    }
    strcat(line,word);
    *lineLend += strlen(word);
}
void WriteLine(const char* line, int lineLend,int numWords) {
    int extraSpaces , spacesToInsert,i,j ;
    //<tính số khoảng tráng dư thừa cho dòng>
    extraSpaces = MAX_LINE_LEN - lineLend ;
    if(extraSpaces == 0)
        puts(line);
    else {
        for(i = 0 ; i < lineLend ; i++) {
            if(line[i] != ' ')
                //<printf charater>
                putchar(line[i]);
            else {
                //<tính số khoảng trống cần bù thêm>
                spacesToInsert = extraSpaces/(numWords - 1);
                //<In 1 space + thêm các space cần bù>
                for(j = 1 ; j <= spacesToInsert + 1; j++)
                    putchar(' ');
                //<Giảm thêm không gian và đếm số từ>
                extraSpaces -= spacesToInsert;
                numWords--;
            }
        }
    }
    putchar('\n');
}
// đang lỗi ở đây:
void ClearLine(char *line, int *lineLend,int *numWords) {
    line[0] = '\0';
    *lineLend = 0;
    *numWords = 0;
}

ví dụ


do cái từ project không đủ kí tự 1 dòng nên nó không in, mà cái này lại phụ thuộc vào cách đọc từ, em chưa khắc phục được. Hóng cao nhân.
Em cám ơn.

Code bạn dài quá nên mình không đọc được hết. Đại khái là nếu là dòng cuối cùng thì bạn xử lí luôn, không cần đợi nó đủ 50 char nữa.

P/s:

Câu này hơi cụt lủn, bỏ đi.

Làm sao để biết dòng cuối cùng vậy ạ. Em viết “Hóng cao nhân” để cho văn vẻ tí, bác để ý quá.

Bạn thử in ra wordLend ngay sau khi đọc để xem các từ có được đọc hết hay không.

Biến lineLend có nghĩa là gì hả bạn?

Không có văn vẻ gì ở câu đó đâu bạn ạ. Nghe hơi trống không đấy.
Mình đi hỏi cũng phải chú ý cách nói năng, trình bày làm sao khiến người khác muốn trả lời.

vâng bác, em rút kinh nghiệm ạ. về vấn đề chính. em debug thì có được được hết. lineLend, để tính xem dòng hiện tại được bao nhiêu ký tự đó bác.

Vấn đề của em là .
giá dụ có n ,đã được căn ,lề, đến dòng cuối cùng có 4 từ như này: anh yêu em nhiều.
nó đọc được từ anh, tiếp đọc từ yêu, tiếp em, tiếp nhiều, đến đấy nó tiếp tục đọc tiếp nhưng trong hàm ReadWord , vì sau nó toàn dấu cách tab hay xuống dòng, nên nó sẽ không qua được vòng While mà mục đich em viết vòng While này là để xử lý : nếu mà viết ____________anh yêu em , vì nó sẽ loại bỏ hết dấu cách trước đó để đọc từ.

vâng bác, em rút kinh nghiệm ạ. về vấn đề chính. em debug thì có được được hết. lineLend, để tính xem dòng hiện tại được bao nhiêu ký tự đó bác.

Vấn đề của em là .
giá dụ có n ,đã được căn ,lề, đến dòng cuối cùng có 4 từ như này: anh yêu em nhiều.
nó đọc được từ anh, tiếp đọc từ yêu, tiếp em, tiếp nhiều, đến đấy nó tiếp tục đọc tiếp nhưng trong hàm ReadWord , vì sau nó toàn dấu cách tab hay xuống dòng, nên nó sẽ không qua được vòng While mà mục đich em viết vòng While này là để xử lý : nếu mà viết ____________anh yêu em , vì nó sẽ loại bỏ hết dấu cách trước đó để đọc từ

Không biết code chạy trên máy bạn thế nào, nhưng mình chạy code của bạn bị lặp vô hạn.

đúng rồi bác, đấy chính là vấn đề của em.

khi em nhập đoạn văn bản thì nó cứ căn thôi, nhập tiếp lại căn tiếp. Chứ nó không dừng được, em đang muốn nó dừng. thì phải xử lý được cái dòng cuối cùng của nó, nếu không nó cứ đợi cho đủ ký tự một dòng là 50 nó căn lề rồi lại tiếp tục đợi, nếu mình nhập toàn dấu cách tab xuống dòng nó sẽ bỏ qua và tim đến bao giờ có từ thì thôi

Khó nhỉ. Mình gợi ý cách khác cho bạn: Đọc vào dữ liệu từ trước, sau đó mới xử lí như bạn đã làm.

Mình cũng không biết nên giải thích code bạn như thế nào, vì code bạn hơi khó đọc.

Phải bỏ quá chứ vì nếu lúc đầu người dùng cứ xuống mấy chục dòng rồi mới nhập dữ liệu thì phải làm sao đây. Khó quá ạ… Bác có hướng nào khác không ạ.

Chuyển qua nhập dữ liệu từ file đi.

Ctrl + Z = EOF. Muốn dừng chỉ cần nhấn Ctrl + Z là xong.
Ngoài ra ch != 'EOF’ là sai r nhóe :3

P/s: Lai nớt thì Ctrl + D nhé. Ctrl + Z thì nó đi tới đâu luôn đấy :penguin:

2 Likes

phù. ez đến vậy sao ta. tks bác

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?