简体   繁体   English

从C中的文件读取数据

[英]Reading data from files in C

So I have a big text file with data in it and I would like to rearrange it. 因此,我有一个很大的文本文件,里面有数据,我想重新排列它。 The data has a combination of integers and floats per each line but I'm only interested in grabbing the first integer, which is either a 1 or 0, and putting it at the end of the line. 数据具有整数和每行浮点数的组合,但是我只想获取第一个整数(即1或0),并将其放在行尾。

For example, in my data file, I have the following line 例如,在我的数据文件中,有以下行
1 0.41 1 44
and I would like to be 我想成为
0.41 1 44 1

This is what I have so far and can't get it to work right. 到目前为止,这是我无法解决的问题。 Thanks. 谢谢。

void main() {
FILE *fp;
FILE *out;

char str[15];
char temp;

fp = fopen("dust.txt", "r+");
out = fopen("dust.dat", "w");

while(fgets(str, sizeof(str), fp) != NULL) {
    temp = str[0];
    str[strlen(str)] = ' ';
    str[strlen(str)+1] = temp;
    str[strlen(str)+2] = '\r';
    str[strlen(str)+3] = '\n';

fwrite(str, 1, strlen(str), out);
}   

fclose(fp);
    fclose(out);
}

This treats the output as a text file (same as input), not a binary. 这会将输出视为文本文件(与输入相同),而不是二进制文件。 I've put code comments where appropriate. 我在适当的地方放置了代码注释。 Your most serious error was in calling strlen after overwriting the string terminator. 您最严重的错误是在覆盖字符串终止符后调用strlen There is only need to call it once anyway. 无论如何,只需要调用一次即可。

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

int main(void)  {                           // main must be type int
    FILE *fp;
    FILE *out;
    char str[100];                          // be generous
    size_t len;

    fp = fopen("dust.txt", "r");
    out = fopen("dust2.txt", "w");          // text file
    if(fp == NULL || out == NULL)
        return 1;

    while(fgets(str, sizeof(str)-3, fp) != NULL) {
        str [ strcspn(str, "\r\n") ] = 0;   // remove trailing newline etc
        len = strlen(str);
        str[len] = ' ';                     // overwrites terminator
        str[len+1] = str[0];                // move digit from front
        str[len+2] = 0;                     // terminate string
        fprintf(out, "%s\n", str + 2);      // write as text
    }   

    fclose(fp);
    fclose(out);
    return 0;
}

Input file: 输入文件:

1 0.41 1 44
0 1.23 2 555

Output file: 输出文件:

0.41 1 44 1
1.23 2 555 0

Think about these 2 lines 想想这两行

str[strlen(str)] = ' ';
str[strlen(str)+1] = temp;

The first sets the null character to ' ' . 第一个将空字符设置为' ' The 2nd calls strlen(str) , yet str no longer has a certain null character which leads to undefined behavior (UB). 第二个调用strlen(str) ,但是str不再具有某个空字符,这会导致未定义行为(UB)。


Suggest instead 建议

str[strcspn(str, "\r\n")] = '\0'; // lop off potential end-of-line characters.
int prefix;
int n;
if (sscanf(str, "%d %n", &prefix, &n) != 1) Handle_Missing_Lead_int();
fprintf(out, "%s %d\n", &str[n], prefix); 

Opening a file in text mode and then writing "\\r\\n" is also a problem as code could write the "\\r" and then take the "\\n" and translate than into "\\r\\n" resulting in "\\r\\r\\n" . 在文本模式下打开文件然后写入"\\r\\n"也是一个问题,因为代码可以写入"\\r"然后取"\\n"并翻译成"\\r\\n"从而导致"\\r\\r\\n" Suggest either opening the file in text mode and writing a single "\\n" (which will be translated as needed) or opening the file in binary mode and writing explicit "\\r\\n" . 建议以文本模式打开文件并编写一个"\\n" (将根据需要进行翻译),或者建议以二进制模式打开文件并编写显式的"\\r\\n"


BTW: Consider being more generous than 15 in char str[15]; 顺便说一句:在char str[15];考虑比15大char str[15]; . Maybe 100? 也许100?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM