在C中读取txt时,如何删除额外的换行符

在C中读取txt时,如何删除额外的换行符,c,C,我是C语言的新手,试着做一些练习 我想将txt文件从 鸡肉 10000 母牛 20000 鸭子 20 羊 1000 到 鸡10000 奶牛20000头 鸭子20 绵羊1000只 然后销毁动物您的行只需将指向变量str0的指针赋给字符串[0] string[0]=str0; 这就是str0更改后字符串[0]更改的原因。它们指向相同的记忆。 要解决这个问题,您必须将str0中的值复制到字符串[0]您应该将问题分成更小的部分,并相互独立地实现-->“分而治之” string[0]=str0;

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

我想将txt文件从

鸡肉
10000
母牛
20000
鸭子
20
羊
1000

鸡10000
奶牛20000头
鸭子20
绵羊1000只

然后销毁动物您的行只需将指向变量str0的指针赋给字符串[0]

string[0]=str0;
这就是str0更改后字符串[0]更改的原因。它们指向相同的记忆。
要解决这个问题,您必须将str0中的值复制到字符串[0]

您应该将问题分成更小的部分,并相互独立地实现-->“分而治之”

string[0]=str0;
在开始编程之前,您应该考虑以下步骤

我将用以下方式分析问题:

  • 露天填充物
  • 开放式出铁口
  • 而不是eof
    • 读取数据集-->2行
      • 读一行->解析动物名称
      • 读一行->解析数字
    • 过滤数据集
    • 写入数据集
  • 关闭文件
我将由此派生以下结构/函数(或使用库函数-取决于类的任务):

  • 结构
    • 数据集{animalName,count}
  • 作用
    • readLine(文件句柄、缓冲指针、maxbuffersize)->成功
    • readDataset(bufferpointer1、bufferpointer2)->成功
    • (parseAnimalName(linebuffer1,buffersize,namebuffer,maxlength)->成功)
    • (parseAnimalCount(linebuffer,NumberInter)->成功)
    • filterAnimal(数据集)->bool
    • writeAnimal(文件句柄,数据集)-->成功
根据使用库解析函数的可能性,我将省略括号中的函数


有了这些独立的小功能,实现整个问题以及分析错误发生的位置应该会容易得多。

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

#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;
}
#包括
#包括
#包括
#包括
#定义限制30
//任意最大项数
#定义最大项目16
//任意最大结果大小
#定义最大结果大小256
//输出字符串必须同时保留动物名称和字符串化整数。
//此整数最多包含11个字符。
//这意味着以字符串格式“%s%d\n”的动物名称
//必须最多使用(最大结果大小-11-空格-\n-NUL)个字符。
#定义最大结果大小((最大结果大小)-14)
内部主(空){
int-retcode;
const char*filename=“file.txt”;
FILE*FILE=fopen(“FILE.txt”、“r”);
if(file==NULL){
fprintf(stderr,“无法打开文件%s:%s”,文件名,strerror(errno));
}
字符文本[最大字符大小+1];
整数;
int id=0;
字符结果[最大项目][最大结果大小];
//动态定义fmt字符串以将fscanf限制为最大值
//格式说明符“%256s”确保fscanf不会读取
//长度超过256个字符(请记住NUL字符需要额外一个字节,
//输出内存必须有257个字符的空间)。
char-fmt[32];
snprintf(fmt,sizeof(fmt),“%%%zus\n”,(size_t)MAX_STR_size);
而(1){
如果(id>=最大项目数)中断;
retcode=fscanf(文件、fmt、文本);
如果(retcode==EOF)中断;
//从fscanf手册页面我们知道“成功后,这些函数返回
//已成功匹配和分配的输入项数“”。如果
//与1不同,然后输入字符串出现问题。可能
//这和我们想象的不一样。
如果(retcode!=1){
fprintf(stderr,“输入与格式说明符不匹配”);
退出(退出失败);
}
retcode=fscanf(文件“%d\n”、&number);
如果(retcode==EOF)中断;
如果(retcode!=1){
fprintf(stderr,“输入与格式说明符不匹配”);
退出(退出失败);
}
//过滤逻辑
如果(数量<限制)继续;
sprintf(结果[id++],“%.*s%d”,最大字符串大小,文本,数字);
}
对于(inti=0;i
使用
'\n'
而不是
10
来表示换行符。为什么不使用读取行的函数来读取行呢?fgets()。那样容易多了。
strcpy(str0,”)行是无意义的-将空字符串添加到字符串末尾没有任何作用。@JonathanLeffler,但我使用
c=getc(file)
int c
,变量c应该是整数对吗?是的,使用
int c
是正确的。并且您避免使用feof()
;只有在成功打开文件流的情况下才能关闭该文件流。有很多好东西,但零碎地读一行是一项艰苦的工作。您可能会想到:
charline1[256],line2[256];而(fgets(line1,sizeof(line1),file)!=0和&fgets(line2,sizeof(line2),file)!=0){…处理两行}
,记住
fgets()
将新行保留在字符串中。@JonathanLeffler good。。。我想我需要更加努力地学习,每一封我能理解的信,但是当他们组成一个句子时,有三分之二的事情对我来说是不可理解的。你有办法继续吗?给我很好的建议。我在大学里学的是机械工程,他们之间的差别太大了