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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29983304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:54:13  来源:igfitidea点击:

How can I move a file pointer to the next line in a file?

cfilepointersc-strings

提问by jkm

I am attempting to write a function that reads through a line, saves each character to an array, manipulates that character array, prints the results to another file, then moves on to the next line in the file.

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

Some sample input/output would be as follows (the purpose of the program is to find the derivative - but that part of the code is working fine.):

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

INPUT:
x
4x^4
91
sinx

OUTPUT:
1
16x^3
0
cosx

The function that I have written so far:

到目前为止我编写的函数:

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
    }
}

My question is: How can I move the file pointer inptr to the next line?

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

回答by Jeegar Patel

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
}

Here you do not need to increment inptrbecause as fscanf()in for loop execute its pointer keeps incrementing so in next while loop you will be at next line.

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



In above code your are missing 1st character of any line.,

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

In while you have read one character but you are not using that and in next for loop again readding character.

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

回答by Brendan

How can I move a file pointer to the next line in a file?

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

Files are a collection of bytes, where the meaning of the bytes depend on the file format.

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

"Plain text" is a group of many different file formats; with different ways to encode characters (EBCDIC, ASCII, many variations of "extended ASCII", UTF-8, UCS-2, UTF-16, ...) and different ways to represent "end of line" ("\n", "\r\n\", "\r").

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

The first step is to decide if your software will assume one specific flavor of "plain text" file format (and be broken for everything else - e.g. when someone transfers a file from a different operating system), or support multiple file formats with explicit control (with a command line argument/s so the user can tell it which file format) and/or if it will try to auto-detect (e.g. assume UTF-8, which will work for ASCII too, and then auto-detect what "end of line" is, possibly by accepting either "\r" or "\n" and then checking to see if '\n" follows "\r" or if "\r" follows "\n").

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

The next step is to convert characters from whatever the file format happens to use into some kind of "standard for you" character set (which might or might not be whatever character set the compiler happens to use) while discarding junk (e.g. things like Unicode "byte order marks") and dealing with the possibility of malformed/corrupt data (e.g. a sequence of bytes that is illegal for UTF-8, a byte that is illegal for ASCII, ...) and dealing with unwanted valid characters (NULL, BELL, DELETE, ...).

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

Immediately after "character set validation, conversion and filtering", you can do "end of line detection" (maybe using a state machine to track "previous character was '\r'" and "previous character was '\n'"; and maybe counting white-space characters and deleting/removing all trailing white-space at the end of the line); and can store the character in the array for later (if it wasn't discarded or "end of line") or call a "process this line" function (if it was an "end of line"). Also don't forget "end of file" - you may reach the end of the file while you're still in the middle of a line (and can handle that by pretending the last line in the file ended with an "end of line" when it didn't).

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

Note that fscanf(inptr, "%c", &in);is extremely bad (you might spend most of your CPU time in this function parsing the format string "%c") and you can use fgetc()as a "less awful" alternative; and all of these functions (fscanf(), fgetc(), fgets(), ...) are mostly unusable anyway (unless you're making unknown compiler specific assumptions about which file format "plain text" actually is and then being broken and wrong for everything else), and most of those functions are slow. Instead; you want to consider using read()(so that you can process a whole buffer full of bytes and avoid the overhead of C library functions and/or kernel API calls for every single byte), or maybe mmap().

请注意,这fscanf(inptr, "%c", &in);是非常糟糕的(您可能会将大部分 CPU 时间花在解析格式字符串的此函数上"%c"),并且您可以将其fgetc()用作“不那么糟糕”的替代方案;并且所有这些函数 ( fscanf(), fgetc(), fgets(), ...) 无论如何大部分都无法使用(除非您对“纯文本”文件格式实际上是哪种文件格式做出未知的编译器特定假设,然后在其他所有内容中都被破坏和错误),并且大多数这些功能中的一个很慢。反而; 您想考虑使用read()(以便您可以处理充满字节的整个缓冲区,并避免每个字节的 C 库函数和/或内核 API 调用的开销),或者mmap().

Finally; you need to make sure that a malicious attacker can't (intentionally) provide a file that has too many characters in a single line. A safety check (e.g. if(i >= MAX) { // Array is full, can't add the next character to the array) is necessary; and can be followed by outputting an error message ("Line too long at line number ...") or by using a dynamically resized array (e.g. use the realloc()function to increase the size of the array).

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

回答by farrouk

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
    }
}

回答by Anthony Ude

Use the function fgets()to read from a file line by line.

使用该函数fgets()逐行读取文件。