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で作業していますが、数字は2桁または3桁になる可能性があるため、これを行う方法がわかりません。

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()

最後の2つのフィールド(制御された数のフィールド)をザッピングする場合は、ザッピングするフィールドの数のカウントを渡して、ループを追加することをお勧めします。このコードは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 に答える