在C中阅读txt时如何删除多余的换行符

时间:2018-12-13 05:51:05

标签: c

我是C语言的新手,请尝试做一些练习

我要从

更改txt文件
Chicken
10000
Cow
20000
Duck
20
Sheep 
1000

Chicken 10000
Cow 20000
Duck 20
Sheep 1000

然后消灭动物<50

Chicken 10000
Cow 20000
Sheep 1000

我的第一步:

读取文件,然后在字符串中加上字母。 像第一个单词“ Chicken”一样,将由“ C”“ h”“ i”“ c”“ k”“ e”“ n”组成。 按照我的代码,当我使用strcpy(str0, "");时,我在strings[0] = str0;之前更改了字符串数组strcpy(str0, "");(str0现在是“ Chicken”),但是当strcpy(str0, "");操作时,我的记忆字符串[0]中的内容也已更改。

如何解决此问题?

这是我的代码:

void append(char* s, char c)
{
    int len = strlen(s);
    s[len] = c;
    s[len+1] = '\0';
}

int main() {
  char str0[256] = "";
  char tmp_char;
  const char *string[2];
  int i, c, line_counter=0;
  FILE *file;
  file = fopen("cry.txt", "r");
  if (file) {
    while ((c=getc(file)) !=EOF) {
      if (c == 10) {
        line_counter++;
        string[0]=str0;
        strcpy(str0, "");
        continue;
      }
      tmp_char = c;
      append(str0, tmp_char);
    }
    fclose(file);
  }
  return 0;
}

3 个答案:

答案 0 :(得分:2)

您应该将问题分成较小的部分,并彼此独立地实施->“分而治之”

在开始编程之前,您应该考虑一下步骤。

我将通过以下方式分析问题:

  • 打开文件
  • 打开文件
  • 虽然不是
    • 读取数据集-> 2行
      • 读一行->解析动物名
      • 读取一行->解析数字
    • 过滤数据集
    • 写入数据集
  • 关闭文件

我将从中派生以下结构/功能(或使用库函数-取决于类的任务):

  • 结构
    • DataSet {animalName,count};
  • 功能
    • readLine(filehandle,bufferpointer,maxbuffersize)->成功
    • readDataset(bufferpointer1,bufferpointer2)->成功
    • (parseAnimalName(linebuffer1,buffersize,namebuffer,maxlength)->成功)
    • (parseAnimalCount(linebuffer,numberpinter)->成功)
    • filterAnimal(DataSet)-> bool
    • writeAnimal(filehandle,DataSet)->成功

根据使用库解析函数的可能性,我会在括号中省略这些函数。

使用这些孤立的小功能,应该更容易实现整个问题并分析错误发生的位置。

答案 1 :(得分:1)

一旦您自己解决了问题,便可以将其与我的解决方案进行比较。我评论得很厉害。

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

#define LIMIT 30
// Arbitrary max number of items
#define MAX_ITEMS 16
// Arbitrary maximum result size
#define MAX_RESULT_SIZE 256
// Output string must keep both animal name and stringified integer.
// This integer will take at most 11 characters.
// It means that in string of format "%s %d\n" the animal name
// must take at most (MAX_RESULT_SIZE - 11 - whitespace - \n - NUL) characters.
#define MAX_STR_SIZE ((MAX_RESULT_SIZE) - 14)

int main(void) {
    int retcode;
    const char *filename = "file.txt";
    FILE *file = fopen("file.txt", "r");

    if (file == NULL) {
        fprintf(stderr, "Failed to open file %s: %s", filename, strerror(errno));
    }

    char text[MAX_STR_SIZE + 1];
    int number;

    int id = 0;
    char results[MAX_ITEMS][MAX_RESULT_SIZE];

    // Dynamically define fmt string to limit fscanf to MAX_STR_SIZE
    // Format specifier "%256s" makes sure that fscanf won't read a string that is 
    // longer than 256 characters (remember about additional one byte for NUL character,
    // output memory must have space for 257 characters).
    char fmt[32];
    snprintf(fmt, sizeof(fmt), "%%%zus\n", (size_t)MAX_STR_SIZE);

    while(1) {
        if (id >= MAX_ITEMS) break;

        retcode = fscanf(file, fmt, text);

        if (retcode == EOF) break;

        // From fscanf manual page we know 'On success, these functions return the 
        // number of input items successfully matched and assigned'. If this is
        // different than 1 then something went wrong with input string. Maybe 
        // It's different than we assumed. 
        if (retcode != 1) {
            fprintf(stderr, "Input is not matching format specifiers");
            exit(EXIT_FAILURE);
        }

        retcode = fscanf(file, "%d\n", &number);

        if (retcode == EOF) break;

        if (retcode != 1) {
            fprintf(stderr, "Input is not matching format specifiers");
            exit(EXIT_FAILURE);
        }

        // Filtering logic
        if (number < LIMIT) continue;

        sprintf(results[id++], "%.*s %d", MAX_STR_SIZE, text, number);
    }

    for(int i = 0; i < id; i++) printf("%s\n", results[i]);

    fclose(file);

    return 0;
}

答案 2 :(得分:0)

您的行仅将指向变量str0的指针分配给字符串[0]

string[0]=str0;

这就是为什么str0更改后字符串[0]也会更改的原因。它们指向相同的内存。 为了解决这个问题,您必须将值从str0复制到字符串[0]