简单的C程序逐行读取文件

时间:2017-07-10 03:48:52

标签: c codeblocks

我想要做的是读取文件的第一行,但是在第一行之后只读取以下行直到命中空格。我的最终目标是通过向所述行添加/减去时间来询问用户他们想要编辑的行。

示例文件

My test file
00:19.1 123456
00:35.4 testing whitespace end

期望输出

1: My test file
2: 00:19.1
3: 00:35.4

代码:

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

int main()
{
    FILE *fptr1, *fptr2;

    char filechar[40];
    char c[50];
    int line_number = 1;
    int replace_line, temp = 1;

    printf("Please enter a file name: ");
    scanf("%s", &filechar);

    if ((fptr1 = fopen(filechar, "r")) == NULL)
    {
        printf("Error locating desired file");
        exit(1);
    }

    c = getc(fptr1);
    while (c != EOF)
    {
        //printf("%d: %c",line_number, c);
        printf("%s",c);
        c = getc(fptr1);
        //line_number++;
    }
    return 0;
}

2 个答案:

答案 0 :(得分:2)

在C中你有面向字符的输入函数(例如getcharfgetc),你有格式化的输入函数(例如{{ 1}} family)然后你有面向行的输入函数。 (例如scanf和POSIX fgets)。当您阅读数据时,面向行的输入函数是该作业的正确工具。 (用getline获取用户输入有许多陷阱,新的(甚至不是那么新的)C程序员陷入其中)

所有面向行的函数在它们填充的缓冲区中读取并包含 scanf。如果稍后将在代码中使用换行符,则可以而且应该从结果缓冲区中删除换行符。一个简单的

'\n'
您只需用 nul-terminatedating 字符覆盖尾随size_t n = strlen (buf); if (buf[n-1] == '\n') buf[--n] = 0; 即可。如果您只是立即打印该行而不是存储它以供以后使用,那么不值得删除换行符(只需在输出格式字符串中考虑它)。

将这些部分组合在一起,您可以读取每一行,只需输出它就可以处理第一行,并且对于每个剩余的行,从读取的完整字符串中解析时间(可能需要一些经过时间)。带有'\n'的{​​{1}}并根据您的指定格式化输出。 E.g。

fgets

注意:您应该通过在sscanf格式字符串中包含字段宽度说明符来防止解析时的缓冲区溢出(例如#include <stdio.h> #define MAXC 64 /* define constants, don't use magic number in code */ int main (int argc, char **argv) { char buf[MAXC] = ""; /* buffer to hold each line -- size as reqd */ int line = 1; FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; if (!fp) { /* validate file open for reading */ fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); return 1; } while (fgets (buf, sizeof buf, fp)) { /* read each line in file */ char et[MAXC] = ""; /* buffer for holding time */ if (line == 1) /* if 1st line, just print */ printf ("%d : %s", line, buf); /* note: \n included by fgets */ else { if (sscanf (buf, "%s", et) != 1) { /* parse up to first whitespace */ fprintf (stderr, "error: invalid conversion, line %d\n", line); return 1; } printf ("%d : %s\n", line, et); /* output elapsed time only */ } line++; /* increment line count */ } if (fp != stdin) fclose (fp); /* close file if not stdin */ return 0; } ,您可以在代码中包含幻数,因为无法直接为sscanf指定可变宽度说明符,除非您创造性地使用{ {1}}提前创建格式字符串 - 但这是另一天...

示例输入文件

sscanf (buf, "%63s", et)

示例使用/输出

sscanf

仔细看看,如果您有任何其他问题,请告诉我。

(注意:我将文件名作为程序的第一个参数,或者如果没有给出文件名,则从sprintf读取.C提供命令行参数 - 使用它们。如果输入,则可以提示输入需要,否则,只需在命令行$ cat dat/et.txt My test file 00:19.1 123456 00:35.4 testing whitespace end

上指定参数就容易了

答案 1 :(得分:0)

如果此C代码可以帮助您,请尝试。它只是逐行读取文件,并用字符串终止字符\0替换空格。

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

char* replace_char(char* str, char find, char replace){
    char *current_pos = strchr(str,find);
    while (current_pos){
        *current_pos = replace;
        current_pos = strchr(current_pos,find);
    }
    return str;
}
int main(void)
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen("/home/developer/CLionProjects/untitled4/download.out", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);
    int count=0;
    while ((read = getline(&line, &len, fp)) != -1) {
        if (count==0) printf("%s", line);
        else printf("%s\n", replace_char(line, ' ', '\0'));
        count++;
    }

    fclose(fp);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);
}

文件

My test file
00:19.1 123456
00:35.4 testing whitespace end

输出

My test file
00:19.1
00:35.4