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

C语言项目:emptyLineCounter函数在n()中触发段错误求助

段错误根源及修复方案

核心错误:scanf越界破坏指针

你的main函数中使用scanf("%s", &opt);读取用户输入,但opt是单个char类型变量,%s格式符会读取整行输入(包括结束符\0),而&opt仅指向1字节的内存空间,写入时会越界覆盖栈上的其他变量(比如v_val文件指针),导致传递给n()的指针变成无效野指针,触发段错误。

修复:将scanf改为读取单个字符,用scanf(" %c", &opt);(前面的空格用于跳过换行符等空白字符)。

次要问题:文件指针位置错误导致统计失效

在v()函数中,你先通过while(fgets(...))将文件指针读到了文件末尾,之后调用emptyLineCounter(dataloger)时,fgets直接返回NULL,无法统计任何内容,返回的emptyLineCount只是初始值1,并非正确结果。

修复:在调用emptyLineCounter前,调用rewind(dataloger);重置文件指针到开头。

其他潜在问题修复

  1. 避免无限循环:checkFileStatus的循环添加重试次数限制,防止文件无法打开时程序卡死。
  2. 修正空行统计初始值:emptyLineCounter的初始值从1改为0,确保统计结果准确。
  3. 调整无效代码位置:将printf("\n");移到switch块末尾,保证每次操作后换行。
  4. 添加文件关闭逻辑:退出时关闭打开的文件,避免资源泄漏。

修复后的完整代码

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

#define MAXSIZE 100

void checkArrayStatus() {
    //check if dynamic arrays (dynamicke polia) are created
}

int checkFileStatus(FILE *file, const char *filename) {
    //checks if file is open or close
    if (file != NULL) {
        return 1;
    } else {
        printf("Neotvoreny subor %s\n", filename);
        return -1;
    }
}

int emptyLineCounter(FILE *file) {
    //empty lines counter; number of empty lines == number of meassurments done
    int emptyLineCount = 0; // 修正初始值为0
    char line[MAXSIZE];

    while (fgets(line, sizeof(line), file) != NULL) {
        int isEmpty = 1; //assume line empty
        for (int i = 0; line[i] != '\0'; i++) {
            if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n' && line[i] != '\r') {
                isEmpty = 0; // Line is not empty
                break;
            }
        }

        if (isEmpty) {
            emptyLineCount++;
        }

    }

    return emptyLineCount;
}

FILE* v() {
    //declare files as empty values
    FILE *dataloger = NULL;

    char *output[] = {"ID. mer. modulu:", "Pozícia modulu:", "Typ mer. veliciny:", "Hodnota:", "Cas merania:", "Datum merania:", ""};

    // 添加重试次数限制,避免无限循环
    int retry = 3;
    while (checkFileStatus(dataloger, "dataloger.txt") == -1 && retry-- > 0) {
        dataloger = fopen("dataloger.txt", "r");
    }  
    // 如果重试后还是打不开,直接退出
    if (!dataloger) {
        exit(EXIT_FAILURE);
    }

    char line[MAXSIZE];
    int pos = 0;
    while (fgets(line, sizeof(line), dataloger) != NULL) {
        if (pos == 7) {
            pos = 0;
        }
        printf("%s ", output[pos]);
        printf("%s", line);
        pos++;

    }

    rewind(dataloger); // 重置文件指针到开头,再统计空行
    int measurement = emptyLineCounter(dataloger);
    printf("统计得到空行数:%d\n", measurement); // 可以打印验证

    return dataloger;
}

int n(FILE **file) {
    if (!*file) { // 先检查指针是否有效,避免rewind空指针
        printf("文件指针无效\n");
        return -1;
    }
    rewind(*file);
    if (checkFileStatus(*file, "dataloger.txt") == -1) {
        printf("Checking ... Failing\n");
        return -1;
    }
    printf("passed\n");

    printf("HERE: %d\n", emptyLineCounter(*file));//length of array based on number of measurmenets

    /*
    int dim1 = 3;
    int dim2 = 6; // Number of "inner" arrays
    char ***dynamicArray = (char ***)malloc(dim1 * sizeof(char **));

    //rework so that it accepts each line instead of input
    for (int i = 0; i < dim1; i++) {
        dynamicArray[i] = (char **)malloc(dim2 * sizeof(char *));
        for (int j = 0; j < dim2; j++) {
            dynamicArray[i][j] = (char *)malloc(256 * sizeof(char)); // Assuming a maximum string length of 255 characters
            printf("Enter a string for element [%d][%d]: ", i, j);
            scanf("%s", dynamicArray[i][j]);
        }
    }*/
    return 0;
}

void c() {
    printf("c\n");
}

void s() {
    printf("s\n");
}

void h() {
    printf("h\n");
}

void z() {
    printf("z\n");
}

int main() {
    //char to store user option
    char opt;

    FILE *v_val = NULL;
        
    //while true keep running -> end at option k
    while(1) {

        scanf(" %c", &opt); // 修正为读取单个字符,跳过空白

        switch(opt){
            //two cases to include capital/lowercase letters
            case 'v':
            case 'V':
                v_val = v();
                //printf("%p", v_val);
                break;
            case 'n':
            case 'N':
                n(&v_val);
                break;
            case 'c':
            case 'C':
                c();
                break;
            case 's':
            case 'S':
                s();
                break;
            case 'h':
            case 'H':
                h();
                break;
            case 'z':
            case 'Z':
                z();
                break;
            case 'k':
            case 'K':
                printf("end\n");
                if (v_val) {
                    fclose(v_val); // 关闭文件,避免资源泄漏
                }
                return 0;
            default:
                printf("Nesprávna možnosť\n"); //check for what the output should be
                break;
        }
        printf("\n"); // 移到这里,每次操作后换行
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:20:35