【问题标题】:strange behaviour in output输出中的奇怪行为
【发布时间】:2013-11-08 18:29:05
【问题描述】:

我的程序无法正常运行。

代码如下:

#include <stdio.h>
#include <stdlib.h>  // for EXIT_SUCCESS and EXIT_FAILURE
#include <ctype.h>
#include <string.h>

void ReadFile(FILE* file) {
    unsigned lines = 0;

    int braces      = 0;
    int curlyBraces = 0;
    int comments    = 0;

    int c;
    char* line = 0;
    unsigned col = 0;

    while ((c = fgetc(file)) != EOF) {
        if(c == '\n') { // new line
            lines++;

            printf("%4d: {%d} (%d) /*%d*/ |%s\n", lines, curlyBraces, braces, comments, line);
            free(line); line = 0;
            col = 0;
        } else {
            // add character to line
            line = (char*)realloc(line, (col+1)*sizeof(char));
            if (line == 0) {
                fprintf(stderr, "error reallocating memory");
                return;
            }
            line[col] = c;
            col++;            

            if (c == '(') {
                braces++;
            } else if (c == ')') {
                braces--;
            } else if (c == '{') {
                curlyBraces++;
            } else if (c == '}') {
                curlyBraces--;
            } else if (c == '/') {
                if (fgetc(file) == '*') {
                    comments++;
                } else {
                    fseek(file, -1, SEEK_CUR);
                }
            } else if (c == '*') {
                if (fgetc(file) == '/') {
                    comments--;
                } else {
                    fseek(file, -1, SEEK_CUR);
                }
            }
        }
    }
}

int main(int argc, char** argv) {
    short lines = 0, words = 0, chars = 0;

    /* check for arguments */
    if (argc == 1) {
        fprintf(stderr, "usage: %s filename\n", argv[0]);
        return EXIT_FAILURE;
    }

    /* open file */
    FILE* file = fopen(argv[1], "r");
    if(file == 0) {
        fprintf(stderr, "error open file '%s'\n", argv[1]);
        return EXIT_FAILURE;
    }

    ReadFile(file);

    if (fclose(file) == EOF) {
        fprintf(stderr, "error in fclose()\n");
        return EXIT_FAILURE;    
    }

    return EXIT_SUCCESS;
}

在输出上我得到了一些奇怪的输出,比如 realloc 覆盖了一些数据...... 我已经尝试过 strcat,但我不能使用常量字符。所以我必须使用 realloc。

这里是输出的简短摘录

P 68: {1} (0) /*0*/ |   / open file *
  69: {1} (0) /*0*/ |   FILE* file = fopen(argv[1], "r");
  70: {2} (0) /*0*/ |   if(file == 0) {
rn EXIT_FA(0) /*0*/ |       fprintf(stderr, "error open file '%s'\n", argv[1]);
r open fi (0) /*0*/ |       return EXIT_FAILURE;
  73: {1} (0) /*0*/ |   }
} 74: {1} (0) /*0*/ |

也许有另一种方法来实现这一点?使用 fgets() 我可以获得整行,但会增加文件中的指针,并且我必须给 fgets() 一个字符数。所以这不是完美的解决方案。

【问题讨论】:

    标签: c realloc


    【解决方案1】:

    你需要在打印出来之前终止你的字符串:

        lines++;
        line[col] = 0; // new
        printf("%4d: {%d} (%d) /*%d*/ |%s\n", lines, curlyBraces, braces, comments, line);
    

    不幸的是,line[col] 在这里超出了范围。所以在添加终止符之前需要realloc 行:

            lines++;
            line = (char*)realloc(line, (col+1)*sizeof(char));
            if (line == 0) {
                fprintf(stderr, "error reallocating memory");
                return;
            }
            line[col] = 0; // new
            printf("%4d: {%d} (%d) /*%d*/ |%s\n", lines, curlyBraces, braces, comments, line);
    

    另外,你知道ungetc吗?您可以将那些 fseek(-1) 替换为 ungetc。

    【讨论】:

    • 谢谢,我忘了终止。但我真的需要为终止字符重新分配内存吗?如果我用 (char*)malloc(sizeof(char)) 启动指针也可以吗?
    • 终止字符位于行尾,因此您需要像对待任何其他字符一样对待它。
    • 如果你改变了'realloc(line, (col+1)*sizeof(char));'到 'realloc(line, (col+2)*sizeof(char));'您不必为最终终止符重新分配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多