【问题标题】:Remove last \n from file从文件中删除最后一个 \n
【发布时间】:2018-10-26 11:27:43
【问题描述】:

我正在过滤 .csv 文件并将输出保存到 .txt 文件。问题是,我的文件和数组中有这个额外的\n 行。我不想在之后编辑 .txt 文件时删除该行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "input3.h"


int main(int argc, char **argv) {
    if (argc < 3) {
        printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
        printf("Beispiel: %s 100 Bayern\n", argv[0]);
        printf("Klein-/Großschreibung beachten!\n");
        exit(1);
    }
    int anzahl = atoi(argv[1]);
    char *bundesland = argv[2];
    char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
    char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
    int bewohner[MAX_LAENGE_ARR];
    int len = read_file("staedte.csv", staedte, laender, bewohner);
    int offset = 0;

     char *a = (char*) malloc(MAX_LAENGE_ARR * sizeof(char));

    for (int i = 0; i < MAX_LAENGE_ARR; ++i) {

        if(strcmp(bundesland,laender[i]) == 0 && bewohner[i] >= anzahl){

            int written = snprintf(a + offset, MAX_LAENGE_STR ,"Die Stadt %s hat %d Einwohner. \n", staedte[i], bewohner[i]);
            offset += written;

        }
    }

    printf("STAEDTE : %s \n", a);
    write_file(&a,1);
    free(a);
}

输出:cat results.txt

Die Stadt München hat 1353186 Einwohner. 
 Die Stadt Nürnberg hat 505664 Einwohner. 
 Die Stadt Augsburg hat 264708 Einwohner. 
 Die Stadt Regensburg hat 135520 Einwohner. 
 Die Stadt Würzburg hat 133799 Einwohner. 
 Die Stadt Ingolstadt hat 125088 Einwohner. 
 Die Stadt Fürth hat 114628 Einwohner. 
 Die Stadt Erlangen hat 105629 Einwohner.
 // a blank line at the end. 

我不能更改 write_file 函数,但它是。

void write_file(char *result[], int len) {
    FILE *fp = fopen("resultat.txt", "w");
    if (fp == NULL){
        perror("resultat.txt");
        exit(1);
    }
    for (int i=0; i<len; i++) {
        fprintf(fp, "%s\n", result[i]);
    }
    fclose(fp);
}

编辑 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "input3.h"


int main(int argc, char **argv) {
    if (argc < 3) {
        printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
        printf("Beispiel: %s 100 Bayern\n", argv[0]);
        printf("Klein-/Großschreibung beachten!\n");
        exit(1);
    }
    int anzahl = atoi(argv[1]);
    char *bundesland = argv[2];
    char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
    char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
    int bewohner[MAX_LAENGE_ARR];
    int len = read_file("staedte.csv", staedte, laender, bewohner);
    int count = 0;

    char **a = malloc(MAX_LAENGE_ARR * sizeof(char*));

    for (int i = 0; i < MAX_LAENGE_ARR; ++i) {

        if(strcmp(bundesland,laender[i]) == 0 && bewohner[i] >= anzahl){
            a[i] = malloc(MAX_LAENGE_STR * sizeof(char));
            snprintf(a[i], MAX_LAENGE_STR ,"Die Stadt %s hat %d Einwohner.", staedte[i], bewohner[i]);
            count++;
        }
    }
    write_file(a, count);
    free(a);
}

结果.txt

(null)
(null)
Die Stadt München hat 1353186 Einwohner.
(null)
(null)
(null)
(null)
(null)

【问题讨论】:

  • 标题说“从文件中删除最后一个\n”,正文说“我不想删除该行”。它是哪一个?你不能忽略空行吗?
  • 问题显然出在write_file 你没有显示出来......
  • 不,我不想通过命令行编辑文本。 @SanderDeDycker
  • @Jabberwocky 已编辑。
  • 这段代码太复杂了。为什么要额外构建一个字符串数组?直接在循环中的输出文件中使用fprintf(),去掉awrite_file()即可。

标签: c


【解决方案1】:

您的 write_file 函数已经添加了 '\n'

fprintf(fp, "%s\n", result[i]);

因此,当您填充传递给该函数的数组时,您不应添加额外的换行符。

即。与其将 a 构建为所有行连接的单个字符串,不如将其构建为字符串数组,在数组中为每行添加一个项目(不包含 '\n')。

为此,您需要allocate memory for this array,然后将当前的snprintf 调用替换为写入该数组中下一项的调用,而不是a + OFFSET

char **a = malloc(MAX_LAENGE_ARR * sizeof(char*));

然后对于每一行:

a[count] = malloc(MAX_LAENGE_STR * sizeof(char));
snprintf(a[count], MAX_LAENGE_STR, ...);

当您不再需要它时,别忘了free the allocated memory

【讨论】:

  • 再次,我无法更改 write_file 函数,谢谢
  • 实际上,我应该将 char 数组和 char 数组的数量传递给 write_file() 数组,但我无法管理。
  • 就像你在编辑中所说的那样。但我不知道怎么做。
  • @aomerk :添加了一些关于如何做到这一点的进一步解释
  • @aomerk :那些“(null)”是因为 if 检查跳过了它们。为避免这种情况,请在 a 数组中使用单独的索引,该索引仅在 if 检查成功时递增,并将正确的数量传递给 write_file
【解决方案2】:

你基本上想要这个:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "input3.h"

...

int main(int argc, char **argv) {
  if (argc < 3) {
    printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
    printf("Beispiel: %s 100 Bayern\n", argv[0]);
    printf("Klein-/Großschreibung beachten!\n");
    exit(1);
  }
  int anzahl = atoi(argv[1]);
  char *bundesland = argv[2];
  char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
  char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
  int bewohner[MAX_LAENGE_ARR];
  int len = read_file("staedte.csv", staedte, laender, bewohner);

  // allocate an array of pointers to char of length MAX_LAENGE_ARR
  char **lines = malloc(MAX_LAENGE_ARR * sizeof(*lines));

  // instead of the line above you could simply write this
  //    char *lines[MAX_LAENGE_ARR];
  // in that case you need to remove the `free(lines);` at the end

  int nboflines = 0; // number of lines processed

  for (int i = 0; i < MAX_LAENGE_ARR; ++i) {

    if (strcmp(bundesland, laender[i]) == 0 && bewohner[i] >= anzahl) {
      // get the size needed for one line (see snprintf documentation for more details)
      int sizeneeded = snprintf(NULL, MAX_LAENGE_STR, "Die Stadt %s hat %d Einwohner. \n", staedte[i], bewohner[i]);

      // allocate the size needed for the line +1 for the NUL terminator
      char *line = malloc(sizeneeded + 1);

      // output to line
      snprintf(line, MAX_LAENGE_STR, "Die Stadt %s hat %d Einwohner. \n", staedte[i], bewohner[i]);    

      lines[nboflines++] = line;
    }
  }


  printf("STAEDTE :");
  for (int i = 0; i < nboflines; ++i)
  {
    printf("%s\n", lines[i]);
  }

  write_file(lines, nboflines);

  // free the individual lines allocated by the malloc
  //  inside the for loop
  for (int i = 0; i < nboflines; ++i)
  {
    free(lines[i]);
  }

  // free the line array allocated just before the for loop
  free(lines);
}
  • 请参阅我添加的 cmets 以获得解释。
  • 我把a的名字改成了更有意义的名字lines

免责声明:

  • 此代码未经测试。
  • 此代码中未进行任何错误检查。
  • 仍有进一步改进的空间。

【讨论】:

    猜你喜欢
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2013-06-05
    • 1970-01-01
    • 2019-06-26
    • 2022-11-04
    • 2017-07-16
    相关资源
    最近更新 更多