【问题标题】:C program with fully justification of text from file文件中文本完全对齐的 C 程序
【发布时间】:2018-08-13 12:41:08
【问题描述】:

这是我的问题陈述:

我有一个与我找不到合适解决方案的部分代码相关的小问题。同样,我不一定要求一个完整的解决方案,我只是遇到了死胡同。我需要从文件中读取行(不知道它们的长度)找到行的最大长度并在每行的单词之间均匀地添加空格,以便它们完全对齐(所有行的大小与最大值相同一)。

到目前为止,这是我的代码:

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

int main() {
    FILE *f;
    char *word;
    int j, i, m, n, c, k, z;
    char aux[255] = "", aux1[255];
    i = 0;
    j = 0;
    char file[100][100];
    char s[100];
    f = fopen("user_input.txt", "r");
    m = 0;

    while (fgets(file[i], sizeof(file[i]), f)) {
        if (m < strlen(file[i]) - 1)
            m = strlen(file[i]) - 1;
        i++;
    }

    for (j = 0; j < i; j++) {
        n = 0;

        for (k = 0; k < strlen(file[j]); k++)
            if (file[j][k] == ' ')
                n++;

        c = (m - strlen(file[j])) / n;

        for (z = 0; z < c; z++)
            aux[z] = ' ';

        for (k = 0; k < strlen(file[j]); k++)
            if (file[j][k] == ' ') {
                strcpy(aux1, file[j] + k + 1);
                strcat(file[j], aux);
                strcat(file[j], aux1);
            }

        printf("%s", file[j]);
    }
}

【问题讨论】:

  • 1) 确切的问题是什么?哪条线路,功能等? 2) 这段代码的格式很差。
  • 看起来您正在攻击如何读取行、获取长度、查找空格和插入空格的基础知识,这很好。但是没有策略的迹象——您需要将问题分解为可管理的步骤。读取文件,将其分成几行,一次处理一行,确定要添加多少个空格,确定在哪里添加它们,实际添加它们,最后产生你的输出。如果您使用变量名/函数名/cmets 来明确代码的每个部分在做什么,这将有所帮助。
  • @AlexanderDmitriev 我会附上一张实际程序的图片
  • 你应该添加#include 这是strlen的需要。确保该文件存在于该位置。
  • @LethalProgrammer 我添加了它,到目前为止它只对齐第一行

标签: c string file


【解决方案1】:

您的代码因多种原因而损坏:

  • 你忘了包含&lt;string.h&gt;
  • 您对最大行长度和行数有硬编码限制,两者都会导致 0.5p 的惩罚
  • 您没有测试fopen() 是否成功,导致无法打开文件时出现未定义的行为。
  • 在读取行时不测试数组边界,如果文件有超过 100 行或 99 字节的片段,则会导致未定义的行为。
  • 您对c = (m - strlen(file[j])) / n; 的计算已向下舍入。在许多情况下,您不会为全文对齐插入足够的空格。
  • aux 没有正确地以 null 结尾,它将不断增长,直到为任何给定行插入最大数量的空格。
  • 插入操作会破坏该行并最终只留下最后一个单词并在之前插入一些空格。
  • 代码格式不正确,由于您不使用{} 进行非平凡的声明,因此难以阅读且容易破解。

这是一个没有此类限制的修改版本:

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

int main() {
    const char *filename = "user_input.txt";
    FILE *f;
    char *line;
    int c, i, len, maxlen, skip, nw, spaces, ns;

    /* open the file */
    if ((f = fopen(filename, "r")) == NULL) {
        fprintf(stderr, "cannot open %s\n", filename);
        return 1;
    }

    /* first pass: determine the maximum line length */
    for (maxlen = len = 0;;) {
        c = getc(f);
        if (c == '\n' || c == EOF) {
            if (maxlen < len)
                maxlen = len;
            len = 0;
            if (c == EOF)
                break;
        } else {
            len++;
        }
    }

    /* allocate the line buffer: maxlen characters plus newline plus '\0' */
    if ((line = malloc(maxlen + 2)) == NULL) {
        fprintf(stderr, "cannot allocate memory for %d bytes\n", maxlen + 2);
        fclose(f);
        return 1;
    }

    /* second pass: read one line at a time */
    rewind(f);
    while (fgets(line, maxlen + 2, f)) {
        len = strlen(line);
        if (len > 0 && line[len - 1] == '\n') {
            /* strip the newline if any */
            line[--len] = '\0';
        }
        /* skip and output initial spaces */
        for (skip = 0; line[skip] == ' '; skip++) {
            putchar(line[skip]);
        }
        /* count the words */
        for (nw = 0, i = skip; i < len; i++) {
            if (line[i] == ' ')
                nw++;
        }
        /* output the text, expanding spaces */
        spaces = maxlen - len;
        for (i = skip; i < len; i++) {
            if (line[i] == ' ') {
                ns = spaces / nw;
                printf("%*s", ns, "");
                spaces -= ns;
                nw--;
            }
            putchar(line[i]);
        }
        putchar('\n');
    }
    free(line);
    fclose(f);
    return 0;
}

【讨论】:

  • 您的分析看起来不错,但您真的认为向 OP 提供考试问题的完整解决方案是否合适?即使他一开始并不想要一个完整的解决方案,这也可能使他面临作弊的指控。
  • 非常感谢您的解决方案,我现在更好地理解了这个问题应该如何实现。
  • @JohnBollinger:我猜你是对的,我没有看到标题计算机编程考试,第二部分,但我认为 OP 更有可能对过去的考试问题进行培训而不是现在参加这个考试。无论如何,给完全可以上网的学生考试是自找麻烦。我提供了一个完整的解决方案,带有教学 cmets 用于教学目的。我比我最初想象的要容易。对于具有初始或尾随空格或多个相邻空格的行,应该使问题陈述更加精确。 均匀的更精确定义也将受到欢迎。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 2015-01-08
  • 1970-01-01
  • 2016-07-29
  • 2013-05-23
  • 1970-01-01
相关资源
最近更新 更多