Remove last \n from file

时间:2018-10-26 11:27:43

标签: c

I am filtering a .csv file and saving the output to a .txt file. The problem is, I have this extra \n line in my file and my array. I don't want to remove the line with editing the .txt file afterwards.

#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);
}

Output : 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. 

I am not allowed to change the write_file function but here it is.

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

EDIT 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);
}

result.txt

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

2 个答案:

答案 0 :(得分:2)

您的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,别忘了。

答案 1 :(得分:0)

您基本上想要这样:

#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);
}
  • 请参阅我添加的注释以获取解释。
  • 我将a的名称更改为更有意义的名称lines

双量分子:

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