C 如何从每行读取特定字符串?

C 如何从每行读取特定字符串?,c,C,我有点绝望,因为我不知道如何创建一个程序,只从输入文件中读取一些数据(单词或数字),然后用这些数据编写另一个文件,但将它们按列表顺序排列。。。 我不知道如何使程序看起来像输入文件的行,例如“序列数:2”,并使它只需要数据“2”就可以存储在新文件中。。。 请帮帮我 我才刚开始 谢谢大家您遇到的问题不是循环,也不是eof的问题 真正的问题是您的解析逻辑不正确 您的输入文件不统一: 不同的会话行中有不同的“模式” 空白行的数量因组而异 空行实际上可以包含任意数量的空格字符 “序列数”行出现在不同组的

我有点绝望,因为我不知道如何创建一个程序,只从输入文件中读取一些数据(单词或数字),然后用这些数据编写另一个文件,但将它们按列表顺序排列。。。 我不知道如何使程序看起来像输入文件的行,例如“序列数:2”,并使它只需要数据“2”就可以存储在新文件中。。。 请帮帮我 我才刚开始


谢谢大家

您遇到的问题不是循环,也不是eof的问题

真正的问题是您的解析逻辑不正确

您的输入文件不统一:

  • 不同的会话行中有不同的“模式”
  • 空白行的数量因组而异
  • 空行实际上可以包含任意数量的空格字符
  • “序列数”行出现在不同组的不同位置
要解析这样的文件,您需要一个更灵活的逻辑来检查每个输入行,收集构建输出行所需的所有数据,然后将其打印到输出文件中

为此,您可以使用一个循环一次只读取一行,然后使用
strncmp
函数测试其内容。
确定行中包含的数据类型后,使用
sscanf
函数将其保存到变量中

以下是执行此任务的代码:

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

int main(int argc, char **argv) {
    FILE *file_in, *file_out;
    char line[200];

    /* intialize these just in case we want to validate the input file */
    int current_session = 0;
    int current_sequences = 0;
    int current_registration = 0;

    /* these arrays can probably be smaller */
    char chars_given[200] = { 0 };
    char chars_recognized[200] = { 0 };

    file_in = fopen("summary.txt", "r");
    if (file_in == NULL) {
        perror("Error opening input file");
        return 1;
    }

    file_out = fopen("ordinated.txt", "w");
    if (file_out == NULL) {
        perror("Error opening output file");
        return -1;
    }

    while (fgets(line, 200, file_in) != NULL) {
        /* check if this is start of session using safe string comparison */
        if (strncmp(line, "session", strlen("session")) == 0) {
            sscanf(line, "session %d", &current_session);
        } else if (strncmp(line, "number of sequences", strlen("number of sequences")) == 0) {
            sscanf(line, "number of sequences: %d", &current_sequences);
        } else if (strncmp(line, "registration", strlen("registration")) == 0) {
            sscanf(line, "registration %d", &current_registration);
        } else if (strncmp(line, "characters given", strlen("characters given")) == 0) {
            sscanf(line, "characters given: %s", chars_given);
        } else if (strncmp(line, "characters recognized", strlen("characters recognized")) == 0) {
            sscanf(line, "characters recognized: %s", chars_recognized);
        } else {
            /* This is a line with no information (blank or separator).
               Time to print results we collected, and reset the variables
               for the next set of results. */
        
            /* check we have enough information to output a line */
            if (current_session > 0 && current_sequences > 0 &&
                current_registration > 0 && strlen(chars_given) > 0) {
            
                /* check if anything was recognized */
                if (strlen(chars_recognized) > 0) {
                    fprintf(file_out, "%d %d %d %s %s\n", current_session, current_registration,
                        current_sequences, chars_given, chars_recognized);
                } else { /* one less parameter to output if nothing was recognized */
                    fprintf(file_out, "%d %d %d %s\n", current_session, current_registration,
                        current_sequences, chars_given);
                }
            
                /* Now reset for next time. If you don't do this, the output line will repeat */
                current_registration = 0;
                chars_given[0] = '\0';
                chars_recognized[0] = '\0';
             }
        }
    }

    /* the last block may not be printed in the loop if there is no empty line after it */
    if (current_session > 0 && current_sequences > 0 &&
        current_registration > 0 && strlen(chars_given) > 0) {
            
        /* check if anything was recognized */
        if (strlen(chars_recognized) > 0) {
            fprintf(file_out, "%d %d %d %s %s\n", current_session, current_registration,
                current_sequences, chars_given, chars_recognized);
        } else { /* one less parameter to output if nothing was recognized */
            fprintf(file_out, "%d %d %d %s\n", current_session, current_registration,
                current_sequences, chars_given);
        }
    }

    fclose(file_in);
    fclose(file_out);

    return 0;
}
#包括
#包括
int main(int argc,字符**argv){
文件*文件输入,*文件输出;
字符行[200];
/*初始化这些,以防我们想要验证输入文件*/
int当前会话=0;
int当前_序列=0;
int当前_注册=0;
/*这些阵列可能更小*/
char chars_给定[200]={0};
已识别的字符[200]={0};
文件_in=fopen(“summary.txt”、“r”);
if(file_in==NULL){
perror(“打开输入文件时出错”);
返回1;
}
file_out=fopen(“ordinated.txt”,“w”);
if(file_out==NULL){
perror(“打开输出文件时出错”);
返回-1;
}
while(fgets(第200行,文件中)!=NULL){
/*使用安全字符串比较检查这是否是会话的开始*/
if(strncmp(第行,“会话”,strlen(“会话”))==0){
sscanf(行,“会话%d”和当前会话);
}else if(strncmp(第行,“序列数”),strlen(“序列数”)==0){
sscanf(第行,“序列数量:%d”和当前_序列);
}else if(strncmp(行,“注册”,strlen(“注册”))==0){
sscanf(行“注册%d”和当前注册);
}else if(strncmp(第行,“给定字符”,strlen(“给定字符”)==0){
sscanf(行,“给定字符:%s”,给定字符);
}else if(strncmp(第行,“已识别字符”,strlen(“已识别字符”)==0){
sscanf(行,“识别字符:%s”,识别字符);
}否则{
/*这是一行没有信息(空白或分隔符)。
打印我们收集的结果并重置变量的时间到了
对于下一组结果*/
/*检查我们是否有足够的信息输出一行*/
如果(当前会话>0&&当前会话序列>0&&
当前注册>0&&strlen(给定字符)>0){
/*检查是否识别出任何东西*/
如果(strlen(字符识别)>0){
fprintf(文件输出,“%d%d%d%s%s\n”、当前会话、当前注册、,
当前字符序列,给定字符,识别字符);
}else{/*如果未识别任何内容,则少输出一个参数*/
fprintf(文件输出,“%d%d%d%s\n”、当前会话、当前注册、,
当前_序列,给定字符);
}
/*现在重置以便下次使用。如果不执行此操作,输出行将重复*/
当前注册=0;
给定的字符[0]='\0';
已识别字符[0]='\0';
}
}
}
/*如果后面没有空行,则最后一个块可能不会在循环中打印*/
如果(当前会话>0&&当前会话序列>0&&
当前注册>0&&strlen(给定字符)>0){
/*检查是否识别出任何东西*/
如果(strlen(字符识别)>0){
fprintf(文件输出,“%d%d%d%s%s\n”、当前会话、当前注册、,
当前字符序列,给定字符,识别字符);
}else{/*如果未识别任何内容,则少输出一个参数*/
fprintf(文件输出,“%d%d%d%s\n”、当前会话、当前注册、,
当前_序列,给定字符);
}
}
fclose(文件输入);
fclose(文件输出);
返回0;
}
这段代码有点难看,但我尽量保持简单

可以通过使用结构、一些标志以及将一些代码移动到单独的函数来清理它


编辑:为简单起见,此代码省略了健全性检查,并假设输入文件未损坏,即第一个非空行始终是会话,行包含所有应包含的信息,等等。

这是否回答了您的问题?谢谢,这可能是一个解决方案…但我不知道如何使用strtokLooking在“序列数:2”你只想读“2”。你怎么知道的?作为一个人,你如何决定只有这些才是相关数据?是什么让你认识到这一点?你必须了解自己的想法,然后向我们解释。这是这行的第22个字符吗?这是这行的最后一个字符吗?如果你不能回答这个问题,那么就不可能让计算机做到这一点。因为计算机比人类愚蠢得多,j