如何将文件指针移动到文件中的下一行?

时间:2015-05-01 07:41:54

标签: c file pointers c-strings

我正在尝试编写一个读取一行的函数,将每个字符保存到一个数组,操作该字符数组,将结果打印到另一个文件,然后移到文件的下一行。

一些示例输入/输出如下(程序的目的是找到派生词 - 但代码的那部分工作正常。):

INPUT:
x
4x^4
91
sinx

OUTPUT:
1
16x^3
0
cosx

到目前为止我写的函数:

int main(){

    FILE *inptr = fopen("functions.txt", "r");
    FILE *outptr = fopen( "derive.txt", "w");

    if(inptr)
        derive(inptr,outptr);

    return 0;
}

void derive(FILE *inptr, FILE *outptr){
    int i;
    char in = '0';
    char array[MAX];

    while((in = fgetc(inptr)) != EOF){
        for(i = 0; in != '\n'; i++){
            fscanf(inptr, "%c", &in);
            array[i] = in;
        }
        manipulate(array, outptr); // Function that finds the derivative and prints to output file
    }
}

我的问题是:如何将文件指针inptr移动到下一行?

4 个答案:

答案 0 :(得分:0)

while((in = fgetc(inptr)) != EOF){
    for(i = 0; in != '\n'; i++){
        fscanf(inptr, "%c", &in);
        array[i] = in;
    }
    manipulate(array, outptr); // Function that finds the derivative and prints to output file
}

这里你不需要增加inptr,因为在for循环中执行fscanf()时它的指针会一直递增,所以在下一个while循环中你将在下一行。

在上面的代码中,你缺少任何一行的第一个字符。

虽然您已经阅读了一个字符,但您没有使用它,而在下一个for循环再次读取字符。

答案 1 :(得分:0)

int main(){

    FILE *inptr = fopen("functions.txt", "r");
    FILE *outptr = fopen( "derive.txt", "w");

    if(inptr)
        derive(inptr,outptr);

    return 0;
}

void derive(FILE *inptr, FILE *outptr){
    int i;
    char in = '0';
    char array[MAX],word[MAX];
    fseek(inptr,0,SEEK_SET);
    while((in = fgetc(inptr)) != EOF){
        for(i = 0; in != '\n'; i++){
            fscanf(inptr, "%c", &in);
            array[i] = in;
            fgets(word,MAX,inptr); 
            /* this should set the cursur of inptr to the next line :D */
        }
        manipulate(array, outptr); // Function that finds the derivative and               prints to output file
    }
}

答案 2 :(得分:0)

  

如何将文件指针移动到文件的下一行?

文件是字节的集合,其中字节的含义取决于文件格式。

“纯文本”是一组许多不同的文件格式;以不同的方式来编码字符(EBCDIC,ASCII,“扩展的ASCII”的许多变体,UTF-8,UCS-2,UTF-16等),并以不同的方式来表示“行尾”(“ \ n” ,“ \ r \ n \”,“ \ r”)。

第一步是确定您的软件将采用一种特定的“纯文本”文件格式(并破坏其他功能,例如,当某人从其他操作系统传输文件时)还是支持多种文件格式使用显式控件(使用命令行参数,以便用户可以告诉它哪种文件格式)和/或是否尝试自动检测(例如,假设UTF-8也适用于ASCII,然后自动执行通过接受“ \ r”或“ \ n”,然后检查“ \ n”是否在“ \ r”之后或“ \ r”是否在“ \ n”之后,来检测“行尾”是什么。)。

下一步是将字符从任何碰巧使用的文件格式转换为某种“适合您的标准”字符集(可能是也可能不是编译器碰巧使用的任何字符集),同时丢弃垃圾(例如诸如Unicode“字节顺序标记”之类的内容),并处理数据格式错误/损坏的可能性(例如,对于UTF-8来说是非法的字节序列,对于ASCII是不合法的字节,...)并处理不必要的有效数据字符(NULL,BELL,DELETE等)。

在“字符集验证,转换和过滤”之后,您可以立即执行“行尾检测”(也许使用状态机来跟踪“先前字符为'\ r'”和“先前字符为'\ n” “;并可能计算空格字符并删除/删除行尾所有的尾随空格);并且可以将字符存储在数组中以备后用(如果未被丢弃或为“行尾”),或者调用“处理此行”函数(如果为“行尾”)。另外请不要忘记“文件结尾”-当您仍处于一行中间时,您可能会到达文件结尾(并且可以通过假装文件中以“行结尾”结尾的最后一行来解决此问题) ”)。

请注意,fscanf(inptr, "%c", &in);非常糟糕(您可能会在此函数中花费大部分CPU时间来解析格式字符串"%c"),并且可以将fgetc()用作“不太可怕”替代而且所有这些功能(fscanf()fgetc()fgets(),...)仍然几乎不可用(除非您针对哪种文件格式“纯文本”做出了未知的编译器特定假设)实际上是其他任何东西都被破坏,然后又被错误地破坏了),而这些功能大多数都很慢。代替;您可能要考虑使用read()(这样就可以处理整个字节缓冲区,并避免每个字节的C库函数和/或内核API调用的开销),或者也许使用mmap()

最后;您需要确保恶意攻击者无法(故意)提供一行中包含太多字符的文件。必须进行安全检查(例如if(i >= MAX) { // Array is full, can't add the next character to the array);并可以输出错误消息(“行号太长,行号...”)或使用动态调整大小的数组(例如,使用realloc()函数来增加数组的大小)。

答案 3 :(得分:-1)

使用功能fgets()逐行读取文件。