C语言 反转文本中的单词

oogrdqng  于 2023-01-08  发布在  其他
关注(0)|答案(1)|浏览(137)

我试图颠倒文本中的单词,例如:

I love you.
You love me.
We're a happy family.

应为:

I evol .uoy
uoY evol .em
er'eW a yppah .ylimaf

我的方法是打开,然后读取文件,之后,创建一个X大小的数组,只要文本中有空字符串,我们就跳过这个步骤。否则,创建一个数组,给第一个数组分配一个较小的大小,这个大小应该等于数组中元素的数量。然后用这个数组更新第一个数组(共享相同的内存分配。)最后,当inc_reset > 1inc_reset每次大于1时,j相对于inc_reset递增。然后在while循环中,我们将第一个索引值与下一个索引值取反,这应该总是为inc_reset = 2更新,并且我们递增j = 1,所以我们总是将前两个值取反。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define MAX_READ 50
int main(){
    int fd;
    fd = open("files/text_1.txt", O_RDWR);
    if (fd == -1){
        printf("Failed");
        exit(EXIT_FAILURE);
    }

    char buffer[MAX_READ+1];
    ssize_t numRead;

    numRead = read(fd, buffer, MAX_READ);
    if (numRead == -1){
        printf("Failed");
        exit(EXIT_FAILURE);
    }

    buffer[numRead] = '\0';
    char temp_buffer[MAX_READ] = {'\0'}; 
    char* var = (char *)malloc(100*sizeof(char));
    char store_i[MAX_READ] = {0};
    int j = 0;
    size_t inc;
    int inc_reset;
    for(int i = 0; i < numRead; i++){
        if (buffer[i] == ' '){
            continue;
        } else {
            store_i[i] = i;
            inc += i;
            inc_reset += i;
            char* var_reset = realloc(var, inc);
            var_reset[i] = buffer[i];
            
            if(inc_reset > 1){
                *var = *var_reset;
                while(j < inc_reset){
                    
                    var[j] = var[j+1];
                    j++;
                }
                inc_reset = 0;
                j = 0;
            }}}

    for(int k = 0; k < sizeof(store_i)/sizeof(store_i[0]); k++){
        //printf("\n%c", var[store_i[k]]);
        buffer[store_i[k]] = var[store_i[k]];
    }

    if (close(fd) == -1){
        printf("Closing");
        exit(EXIT_FAILURE);
    }
    
    return 0;
}
shyt4zoc

shyt4zoc1#

你的方法太复杂了。
如果你可以假设一行的长度是固定的LEN,那么我建议你用fgets()来读取一行,然后你用strpbrk()来处理这行,找到你的分隔符reverse() it,然后strchr()来找到一个非分隔符,并打印出你的分隔符。如果你有多个连续的分隔符,这是健壮的。下面的代码从stdin读取输入,所以你可以称之为./a.out < files/text_t.txt,或者你可以修改代码来读取这个固定的文件。
如果不想采用固定的行长度,可以动态分配s,然后根据需要调整大小(如果! feof()和s的最后一个字节不是\n),然后追加另一个块。

#include <stdio.h>
#include <string.h>
#define LEN 1024
#define SEP " \n"

void swap(char *a, char *b) {
    char tmp = *a;
    *a = *b;
    *b = tmp;
}

char *reverse(char *begin, char *end) {
    char *s = begin;
    for(end--; begin < end; begin++, end--) {
        swap(begin, end);
    }
    return s;
}

int main() {
    char s[LEN];
    while(fgets(s, LEN, stdin)) {
        char *begin = s;
        while(*begin) {
            char *end = strpbrk(begin, SEP);
            if(!end) break;
            printf("%.*s", (int) (end - begin), reverse(begin, end));
            begin = end;
            while(strchr(SEP, *end)) end++;
            printf("%.*s", (int) (end - begin), begin);
            begin = end;
        }
    }
}

和示例运行:

cat <<EOF | ./a.out
I love you.
You love me.
We're a happy family.
EOF
I evol .uoy
uoY evol .em
er'eW a yppah .ylimaf

另一种方法是mmap()输入文件(使用MAP_PRIVATE标志),然后使用下面类似的算法,如内部while()循环。如果愿意,可以将打印延迟到最后。

相关问题