0

我有一个文本文件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中工作,但由于数字可以有两位或三位数字,我不知道该怎么做。

4

1 回答 1

2

的几个用途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';
    }
}

似乎工作的编译代码。请注意,给定一个包含单个逗号的字符串,它将删除该逗号。如果您不希望这种情况发生,那么您必须更加努力地工作。

测试代码zap_last_field()

#include <string.h>

extern void zap_last_field(char *line);

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';
    }
}

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

int main(void)
{
    char *line = malloc(4096);
    if (line != 0)
    {

        while (fgets(line, 4096, stdin) != 0)
        {
            printf("Line: %s", line);
            zap_last_field(line);
            printf("Zap1: %s\n", line);
        }
        free(line);
    }
    return(0);
}

这已经过审查,valgrind并且在原始数据文件和下面列出的损坏数据文件上都可以。动态内存分配可以valgrind最大程度地发现任何问题。

我强烈怀疑评论中报告的核心转储发生是因为替代测试代码试图将文字字符串传递给函数,这将不起作用,因为文字字符串通常不可修改,并且此代码在原地修改字符串。

测试代码zap_last_n_fields()

如果您想删除最后几个字段(受控数量的字段),那么您可能需要传入要删除的字段数的计数并添加一个循环。请注意,此代码使用 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);
}

示例运行 - 使用您的data.txt作为输入:

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
,
于 2013-01-08T00:15:48.563 回答