You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言文本自动换行程序输出不符问题求助

C语言文本自动换行程序问题修复

我是C语言新手,正在编写一个文本自动换行程序,要求处理后每行长度不超过指定的linewidth值。其中readfile函数负责从文件读取内容到字符串数组(数组每个元素对应文件一行),需要实现逻辑将内容转换为符合长度限制的newtext字符串数组。

目前程序输出和预期不符,尝试过调整结束索引、编写单独的空格跳过循环都没解决问题:

  • 预期效果:每行长度不超过设定值,优先在单词末尾换行,不截断单词;若单个单词长度超过限制,才强制截断
  • 当前输出:存在单词被截断、换行位置错误的情况

原程序代码

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

int readfile(char* filename, char*** bufp)
{
    FILE* fp = fopen(filename, "r");
    char** buf = NULL;
    int numlines = 0;
    char tmp[1000];
    while (fgets(tmp, sizeof(tmp), fp)) {
        if (numlines % 16 == 0) {
            buf = (char**)realloc(buf, (numlines+16) * sizeof(char*));
        }
        int len = strlen(tmp);
        tmp[len-1] = 0;
        buf[numlines] = malloc(len + 1);
        strcpy(buf[numlines], tmp);
        numlines++;
    }
    *bufp = buf;
    return numlines;
}

void print_text(char** lines, int numlines) {
    for (int i=0; i<numlines; i++) {
        printf("%s\n", lines[i]);
    }
}

int main(int argc, char** argv) {
    char** text;
    int numlines = readfile(argv[1], &text);
    int linewidth = atoi(argv[2]);

    char** newtext = NULL;
    int newnumlines = 0;

    for (int i = 0; i < numlines; i++)
    {
        char * line = text[i];
        int length = strlen(line);
        int x = 0;
        int start = 0;
        
        while (start < length) {
            // Calculate the end index of the current line segment
            int end = start + linewidth;

            // Adjust the end index if it falls within a word
            while (end > start && end < length && line[end] != ' ') {
                end--;
            }
            
            char *newline = malloc(end - x + 1 + 1); 
            strncpy(newline, line + start, end - start);
            newline[end - start] = '\0'; 
            
            newtext = realloc(newtext, (newnumlines + 1) * sizeof(char*));
            newtext[newnumlines++] = newline;
            
            start =  end;
            while(start < length && line[start] == ' ')
            {
                start++;
            }
        }
        
    }

    for(int i = 0; i < newnumlines; i++) {
        // Skip printing empty lines
        if (strlen(newtext[i]) > 0) {
            printf("%s\n", newtext[i]);
        }
    }
    
    //freeing memory
    for(int i = 0; i < numlines; i++){
        free(text[i]);
    }
    free(text);
    
    for(int i = 0; i < newnumlines; i++){
        free(newtext[i]);
    }
    free(newtext);
    
    return 0;
}

问题分析与修复

原代码存在4个关键错误导致输出异常,修复后的代码如下:

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

int readfile(char* filename, char*** bufp)
{
    FILE* fp = fopen(filename, "r");
    if (!fp) {
        perror("Failed to open file");
        return 0;
    }
    char** buf = NULL;
    int numlines = 0;
    char tmp[1000];
    while (fgets(tmp, sizeof(tmp), fp)) {
        if (numlines % 16 == 0) {
            buf = (char**)realloc(buf, (numlines+16) * sizeof(char*));
            if (!buf) {
                perror("Realloc failed");
                exit(EXIT_FAILURE);
            }
        }
        int len = strlen(tmp);
        // 处理文件最后一行没有换行符的情况
        if (tmp[len-1] == '\n') {
            tmp[len-1] = 0;
            len--;
        }
        buf[numlines] = malloc(len + 1);
        if (!buf[numlines]) {
            perror("Malloc failed");
            exit(EXIT_FAILURE);
        }
        strcpy(buf[numlines], tmp);
        numlines++;
    }
    fclose(fp);
    *bufp = buf;
    return numlines;
}

int main(int argc, char** argv) {
    if (argc != 3) {
        printf("Usage: %s <filename> <linewidth>\n", argv[0]);
        return 1;
    }
    char** text;
    int numlines = readfile(argv[1], &text);
    if (numlines == 0) {
        return 1;
    }
    int linewidth = atoi(argv[2]);
    if (linewidth <= 0) {
        printf("Invalid linewidth\n");
        return 1;
    }

    char** newtext = NULL;
    int newnumlines = 0;

    for (int i = 0; i < numlines; i++)
    {
        char *line = text[i];
        int length = strlen(line);
        int start = 0;
        
        while (start < length) {
            int end = start + linewidth;
            // 确保end不超过字符串长度
            if (end > length) {
                end = length;
            }

            // 回退到最近的空格,避免截断单词
            while (end > start && end < length && line[end] != ' ') {
                end--;
            }

            // 处理超长单词:如果回退到start,直接截断到linewidth
            if (end == start) {
                end = start + linewidth;
                if (end > length) {
                    end = length;
                }
            }

            // 分配正确的内存:end-start是字符数,加1存终止符
            char *newline = malloc(end - start + 1); 
            if (!newline) {
                perror("Malloc failed");
                exit(EXIT_FAILURE);
            }
            strncpy(newline, line + start, end - start);
            newline[end - start] = '\0'; 
            
            newtext = realloc(newtext, (newnumlines + 1) * sizeof(char*));
            if (!newtext) {
                perror("Realloc failed");
                exit(EXIT_FAILURE);
            }
            newtext[newnumlines++] = newline;
            
            // 更新start,跳过后续空格(只有当end没到末尾时才处理)
            start = end;
            if (start < length && line[start] == ' ') {
                while(start < length && line[start] == ' ') {
                    start++;
                }
            }
        }
    }

    for(int i = 0; i < newnumlines; i++) {
        printf("%s\n", newtext[i]);
    }
    
    // 释放内存
    for(int i = 0; i < numlines; i++){
        free(text[i]);
    }
    free(text);
    
    for(int i = 0; i < newnumlines; i++){
        free(newtext[i]);
    }
    free(newtext);
    
    return 0;
}

关键修改点

  1. 边界处理:添加end不超过字符串长度的判断,避免数组越界访问
  2. 超长单词兼容:当回退end到start时,直接截断到linewidth,避免无限循环
  3. 内存分配修正:去掉无用变量x,按end-start+1分配内存,确保能存下终止符
  4. 空格跳过逻辑优化:只有当end未到字符串末尾时,才跳过后续空格,避免越界
  5. 增加错误检查:添加文件打开、内存分配的错误处理,提升程序稳定性

内容的提问来源于stack exchange,提问作者dev jonston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:52:35