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

C语言读取文件生成字符串数组后,如何移除其中的空元素?

问题:C语言筛选表达式数组出现空行,导致符合条件的表达式未正常输出

文本文件中的表达式示例

X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
(X&Y)|Z&(A|B
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
(A|B)|(C|D)&(D
!A|(B&C)

筛选后的异常结果(含空行)

X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
         //此处为空行
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
         //此处为空行

问题代码

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

#define MAX 200
#define MAXLEN 100

int main()
{
    FILE *dat;
    int number_of_elements;
    char str[MAX][MAXLEN];
    int NumberOfRightBracket=0;
    int NumberOFLeftBracket=0;
    int NumberOfOperators=0;
    int Number=0;
    int i=0;
    char g[200][MAXLEN];
    dat=fopen("dat.txt","r");
    if(dat==NULL)
    {
        printf("Error");
    }
    while(!feof(dat) && !ferror(dat))
    {
        if(fgets(str[i],100,dat)!=NULL)
        str[i][strcspn(str[i],"\n")] = 0;

        char p[100];
        strcpy(p,str[i]);

        for(int o=0;o<strlen(p);o++)
        {
            if(p[o]=='(')
                NumberOFLeftBracket++;
            else if(p[o]==')')
                NumberOfRightBracket++;
            else if(p[o]=='*' || p[o]=='|' || p[o]=='&' || p[o]=='!')
                NumberOfOperators++;
        }


        if(NumberOfRightBracket!=0 && NumberOFLeftBracket!=0 && NumberOfRightBracket==NumberOFLeftBracket)
        {
           strcpy(g[i],p);
           Number++;

        }
        else if(NumberOfRightBracket==0 && NumberOFLeftBracket==0 && NumberOfOperators==1)
        {
            strcpy(g[i],p);

            Number++;

        }

        NumberOfRightBracket=0;
        NumberOFLeftBracket=0;
        NumberOfOperators=0;
        i++;
    }

   for(int k=0;k<Number;k++)
   {
     printf("%s\n",g[k];
   }

}

问题原因及修复方案

核心问题

  1. 数组索引不匹配:用原文件的行索引i给结果数组g赋值,不符合条件的行不会写入g[i],但Number计数跳过这些行,导致g数组中存在未初始化的空元素,输出时显示空行。
  2. 语法错误:printf语句缺少右括号,文件打开失败后未终止程序,未关闭文件导致资源泄漏。
  3. 循环逻辑缺陷:while(!feof(dat))容易多读一行,导致额外的空元素。

修复步骤

  1. 独立维护结果数组索引:用单独的变量resIdx管理结果数组的写入位置,符合条件时才递增,避免空元素占位。
  2. 修正语法与资源问题:补全printf括号,添加文件打开失败的返回逻辑,结束时关闭文件。
  3. 优化读取循环:直接用fgets的返回值判断读取是否成功,避免多读空行。

修复后的完整代码

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

#define MAX 200
#define MAXLEN 100

int main()
{
    FILE *dat = fopen("dat.txt", "r");
    if (dat == NULL)
    {
        printf("Error opening file\n");
        return 1;
    }

    char str[MAX][MAXLEN];
    char g[MAX][MAXLEN];
    int resIdx = 0; // 结果数组的独立索引
    int lineIdx = 0;

    while (fgets(str[lineIdx], MAXLEN, dat) != NULL)
    {
        // 移除换行符
        str[lineIdx][strcspn(str[lineIdx], "\n")] = '\0';
        char *p = str[lineIdx];

        int leftBracket = 0, rightBracket = 0, operators = 0;
        for (int o = 0; o < strlen(p); o++)
        {
            if (p[o] == '(')
                leftBracket++;
            else if (p[o] == ')')
                rightBracket++;
            else if (p[o] == '*' || p[o] == '|' || p[o] == '&' || p[o] == '!')
                operators++;
        }

        // 判断是否符合筛选条件
        if ((leftBracket > 0 && rightBracket > 0 && leftBracket == rightBracket) ||
            (leftBracket == 0 && rightBracket == 0 && operators == 1))
        {
            strcpy(g[resIdx++], p);
        }

        lineIdx++;
    }

    // 输出所有符合条件的表达式
    for (int k = 0; k < resIdx; k++)
    {
        printf("%s\n", g[k]);
    }

    fclose(dat);
    return 0;
}

修复后效果

运行后将输出所有符合条件的表达式,无空行:

X&Y
X|Y
!X
(X|Y)|Z
(X&Y)|Z
(X&Y)&Z
((X|Y)|Z)&((A|B)|(C&D))
(X&Y)|(Z&(A|B))
(A|B)&(!C)
A|(B&(C&(D|E)))
((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
(A|B)|(C&D)&(D|E)
!A&(B|C)
!A|(B&C)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30