printf 输出出现意外间距

问题描述 投票:0回答:1

我有以下代码,并且从我用来调试的一些打印中得到了奇怪的输出,只是想问清楚为什么它会这样。

int *counter(const char *filename, bool bytes_flag, bool words_flag, bool lines_flag) {
    int *counts = malloc(sizeof(int) * 3);
    int line_count = 0;
    int word_count = 0;
    int byte_count = 0;
    size_t line_size = LINE_MAX;
    FILE *file_stream;
    char *line_buffer;

    printf("%d %d %d\n", line_count, word_count, byte_count);

    file_stream = fopen(filename, "r");

    if (file_stream == NULL) {
        printf("File count not be opened.\n");
    } else {
        line_buffer = (char *)malloc(line_size);
        while (getline(&line_buffer, &line_size, file_stream) != EOF) {
            if (lines_flag) {
                line_count++;
            }
            printf("LINE - %s\n", line_buffer);

            for (int i = -1; line_buffer[i] != '\n'; i++) {
                printf("%c ", line_buffer[i]);
                byte_count++;
                if (isspace(line_buffer[i]) && !isspace(line_buffer[i - 1])) {
                    word_count++;
                }
            }
            printf("\n");
            byte_count++; //Count last \n character
        }
        fclose(file_stream);
        
        printf("\n");
        printf("%d\n", line_count);
        printf("%d\n", word_count);
        printf("%d\n", byte_count);
        printf("\n");

        counts[0] = line_count;
        counts[1] = word_count;
        counts[2] = byte_count;
    }
    return counts;
}

我的结果是

LINE - The Project Gutenberg eBook of The Art of War

    T h e   P r o j e c t   G u t e n b e r g   e B o o k   o f   T h e   A r t   o f   W a r 
LINE -     

         
LINE - This ebook is for the use of anyone anywhere in the United States and

 T h i s   e b o o k   i s   f o r   t h e   u s e   o f   a n y o n e   a n y w h e r e   i n   t h e   U n i t e d   S t a t e s   a n d 

3
24
130

来自文本文件

The Project Gutenberg eBook of The Art of War
    
This ebook is for the use of anyone anywhere in the United States and

注意第二行似乎有 4 个空格。我认为这是罪魁祸首,但如果这一行出现在打印字符之后,即下一次迭代,为什么会在

T h e
之前打印呢?

c printf stdout
1个回答
0
投票

该代码具有未定义的行为,因为您在

中访问数组开头之前的字节
    for (int i = -1; line_buffer[i] != '\n'; i++)

-1
开始没有意义,只有在
line_buffer[i - 1]
时才应进行测试
i > 0

此外,如果

line_buffer[i]
是空终止符,则应始终停止,以防文件中的最后一行没有尾随换行符。

测试从空间到非空间的转换更简单。

这是修改后的版本:

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

int *counter(const char *filename, bool bytes_flag, bool words_flag, bool lines_flag) {
    int *counts = malloc(sizeof(int) * 3);
    if (counts == NULL) {
        fprintf(stderr, "Cannot allocate memory\n");
        return NULL;
    }

    int line_count = 0;
    int word_count = 0;
    int byte_count = 0;

    printf("%d %d %d\n", line_count, word_count, byte_count);

    FILE *file_stream = fopen(filename, "r");
    if (file_stream == NULL) {
        fprintf(stderr, "Cannot open file %s: %s\n", filename, strerror(errno));
    } else {
        size_t line_size = 0;
        char *line_buffer = NULL;

        while (getline(&line_buffer, &line_size, file_stream) >= 0) {
            if (lines_flag) {
                line_count++;
            }
            printf("LINE - %s\n", line_buffer);

            unsigned char last = '\n', ch;
            for (size_t i = 0; (ch = line_buffer[i]) != '\0'; i++) {
                printf("%c ", ch);
                byte_count++;
                if (!isspace(ch) && isspace(last)) {
                    word_count++;
                }
                last = ch;
            }
        }
        fclose(file_stream);
        
        printf("\n");
        printf("%d\n", line_count);
        printf("%d\n", word_count);
        printf("%d\n", byte_count);
        printf("\n");
    }
    counts[0] = line_count;
    counts[1] = word_count;
    counts[2] = byte_count;
    return counts;
}
© www.soinside.com 2019 - 2024. All rights reserved.