【问题标题】:"Overwrite" repeated values in a file (C) [closed]“覆盖”文件中的重复值(C)[关闭]
【发布时间】:2014-08-09 09:20:48
【问题描述】:

您好,我有一个小问题,我还没有找到解决方案。我有一个包含以下信息的文件(data.txt):

5,5,6,2,5,2
1,4,2,3,7,2
4,2,5,2,3,4
5,5,6,2,5,2
4,5,2,6,2,4
2,1,5,6,3,2

我想把所有重复的行都设置为0,例如:5,5,6,2,5,2出现两次,所以最终的文件必须如下所示:

0,0,0,0,0,0
1,4,2,3,7,2
4,2,5,2,3,4
0,0,0,0,0,0
4,5,2,6,2,4
2,1,5,6,3,2

我已尝试使用辅助文件,但无法获得解决方案,如果有任何帮助,我将不胜感激。

我可以将两行中的任何一行设置为 0,但不能同时设置为 0,如果同一行出现两次以上,则设置为 0。

【问题讨论】:

  • 请贴出你已经写好的代码。
  • 输入文件中矩阵的宽高是多少?它总是相同的宽度吗?它总是一样的高度吗?
  • 您的问题是什么?,您对我们有什么期望?
  • 显示将它们中的每一个都设置为零但不都设置为零的代码

标签: c file overwrite


【解决方案1】:

您可以通过以下方式实现:

  • 首先在"r+"模式下打开输入/输出文件
  • 系统地将文件中的字符逐行放入字符数组数组中
  • 行间比较,成对时将逗号以外的字符设为零
  • 在文件中回溯
  • 将行写回文件,用新行分隔

要正确检测配对,您可以遵循以下逻辑:

  • 选择一行,创建一个变量并将其设置为1
  • 将该行与其他行进行比较
  • 如果匹配,请将变量设置为 0 并继续将您的行与其他行进行比较
  • ...直到最后,每次匹配将非逗号字符替换为零字符
  • 在检查完所有内容后,根据您最初设置为 1 的变量的状态修改或不修改您最初选择的行

这是一个有效的代码,除非你没有足够的内存,否则应该可以正常工作:

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

void settozero( char * line ) {
    for ( int i = 0; line[i] != '\0'; i++ )
        if ( line[i] != ',' )
            line[i] = '0';
}

int main( ) {

    char ** lines = NULL;
    FILE * input;

    if ( ( input = fopen( "input", "r+" ) ) == NULL ) {
        printf( "error at line %d", __LINE__ );
        return -1;
    }

    int currentchar;
    int newline = 1;
    int linecount = 0;
    int lineindex;
    int linesize;
    while ( ( currentchar = fgetc( input ) ) != EOF ) {
        if ( newline ) {
            linecount++;
            lineindex = 0;
            linesize = 128;
            lines = realloc( lines, linecount * sizeof * lines );
            lines[linecount - 1] = malloc( linesize );
            newline = 0;
        }
        if ( lineindex == linesize ) {
            linesize *= 3;
            lines[linecount - 1] = realloc( lines[linecount - 1], linesize );
        }
        if ( currentchar == '\n' ) {
            newline = 1;
            currentchar = '\0';
        }
        lines[linecount - 1][lineindex++] = currentchar;
    }

    if ( !newline ) {
        if ( lineindex == linesize )
            lines[linecount - 1] = realloc( lines[linecount - 1], linesize + 1 );
        lines[linecount - 1][lineindex] = '\0';
    }

    int * linestoskip = calloc( linecount, sizeof * linestoskip );

    for ( int i = 0; i < linecount; i++ ) {
        if ( linestoskip[i] )
            continue;

        int unique = 1;
        for ( int j = i + 1; j < linecount; j++ ) {
            if ( linestoskip[j] )
                continue;

            if ( strcmp( lines[i], lines[j] ) == 0 ) {
                unique = 0;
                settozero( lines[j] );
                linestoskip[j] = 1;
            }
        }
        if ( !unique )
            settozero( lines[i] );
    }

    free( linestoskip );
    fseek( input, 0L, SEEK_SET );

    for ( int i = 0; i < linecount; i++ ) {
        for ( int j = 0; lines[i][j] != '\0'; j++ ) {
            fputc( lines[i][j], input );
        }
        if ( i != linecount - 1 || newline )
            fputc( '\n', input );
        free( lines[i] );
    }

    free( lines );

    putchar( 10 );
    return 0;
}

【讨论】:

  • 效果很好,非常感谢!
  • @LuisIbarra 不客气,兄弟,但这确实不是你应该在这里提问的方式。你应该展示你一直在努力的失败尝试。我真的不应该这样回答,但我还是这样做了,因为我认为这可能会有所帮助,而且我有时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
相关资源
最近更新 更多