Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从文本文件中删除行的最后成员_C_Char - Fatal编程技术网

C 从文本文件中删除行的最后成员

C 从文本文件中删除行的最后成员,c,char,C,Char,我有一个文本文件,名为data.txt,我想删除每行的最后成员: 以下是文本文件: 2031,2,0,0,0,0,0,0,54,0, 2027,2,0,0,0,0,0,0,209,0, 2029,2,0,0,0,0,0,0,65,0, 2036,2,0,0,0,0,0,0,165,0, 我想将其删除,使其成为: 2031,2,0,0,0,0,0,0, 2027,2,0,0,0,0,0,0, 2029,2,0,0,0,0,0,0, 2036,2,0,0,0,0,0,0, 我使用的是C,但由于数

我有一个文本文件,名为
data.txt
,我想删除每行的最后成员:

以下是文本文件:

2031,2,0,0,0,0,0,0,54,0,
2027,2,0,0,0,0,0,0,209,0,
2029,2,0,0,0,0,0,0,65,0,
2036,2,0,0,0,0,0,0,165,0,
我想将其删除,使其成为:

2031,2,0,0,0,0,0,0,
2027,2,0,0,0,0,0,0,
2029,2,0,0,0,0,0,0,
2036,2,0,0,0,0,0,0,

我使用的是C,但由于数字可以有两到三个数字,我不确定如何执行此操作。

使用
strrchr()
可以完成以下工作:

#include <string.h>

void zap_last_field(char *line)
{
    char *last_comma = strrchr(line, ',');
    if (last_comma != 0)
    {
        *last_comma = '\0';
        last_comma = strrchr(line, ',');
        if (last_comma != 0)
            *(last_comma + 1) = '\0';
    }
}
这已通过
valgrind
检查,在原始数据文件和下面列出的损坏数据文件上都正常。动态内存分配是为了给
valgrind
发现任何问题的最大机会

我强烈怀疑注释中报告的核心转储是因为替代测试代码试图将文本字符串传递给函数,但这不会起作用,因为文本字符串通常不可修改,而此代码会在原位修改字符串

测试
zap\u last\u n\u字段()的代码
如果要清除最后两个字段(字段的受控数量),则可能需要传入要清除的字段数量的计数并添加循环。请注意,此代码使用VLA,因此需要C99编译器

#include <string.h>

extern void zap_last_n_fields(char *line, size_t nfields);

void zap_last_n_fields(char *line, size_t nfields)
{
    char *zapped[nfields+1];

    for (size_t i = 0; i <= nfields; i++)
    {
        char *last_comma = strrchr(line, ',');
        if (last_comma != 0)
        {
            zapped[i] = last_comma;
            *last_comma = '\0';
        }
        else
        {
            /* Undo the damage wrought above */
            for (size_t j = 0; j < i; j++)
                *zapped[j] = ',';
            return;
        }
    }
    zapped[nfields][0] = ','; 
    zapped[nfields][1] = '\0';
}

#include <stdio.h>

int main(void)
{
    char line1[4096];

    while (fgets(line1, sizeof(line1), stdin) != 0)
    {
        printf("Line: %s", line1);
        char line2[4096];
        for (size_t i = 1; i <= 3; i++)
        {
            strcpy(line2, line1);
            zap_last_n_fields(line2, i);
            printf("Zap%zd: %s\n", i, line2);
        }
    }
    return(0);
}
它还可以正确处理以下文件:

2031,0,0,
2031,0,
2031,
2031
,

它必须是C吗?有很多脚本语言可以在大约3.14行代码中实现这一点。我知道,但我想将它与我已有的更大的c语言程序集成。这是有道理的。现实世界有一个习惯,妨碍我们使用简单的解决方案。它给了我“分段错误(内核转储)”,我想这是因为您在测试代码中传递了一个字符串文本…请参阅更新,显示
zap\u last\u field()的测试代码。
Line: 2031,2,0,0,0,0,0,0,54,0,
Zap1: 2031,2,0,0,0,0,0,0,54,
Zap2: 2031,2,0,0,0,0,0,0,
Zap3: 2031,2,0,0,0,0,0,
Line: 2027,2,0,0,0,0,0,0,209,0,
Zap1: 2027,2,0,0,0,0,0,0,209,
Zap2: 2027,2,0,0,0,0,0,0,
Zap3: 2027,2,0,0,0,0,0,
Line: 2029,2,0,0,0,0,0,0,65,0,
Zap1: 2029,2,0,0,0,0,0,0,65,
Zap2: 2029,2,0,0,0,0,0,0,
Zap3: 2029,2,0,0,0,0,0,
Line: 2036,2,0,0,0,0,0,0,165,0,
Zap1: 2036,2,0,0,0,0,0,0,165,
Zap2: 2036,2,0,0,0,0,0,0,
Zap3: 2036,2,0,0,0,0,0,
2031,0,0,
2031,0,
2031,
2031
,