【问题标题】:Reading data from files in C从 C 中的文件中读取数据
【发布时间】:2016-04-21 18:14:28
【问题描述】:

所以我有一个包含数据的大文本文件,我想重新排列它。数据每行都有整数和浮点数的组合,但我只对获取第一个整数(1 或 0)感兴趣,并将其放在行尾。

例如,在我的数据文件中,我有以下行
1 0.41 1 44
我想成为
0.41 1 44 1

这是我目前所拥有的,无法让它正常工作。谢谢。

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

【问题讨论】:

  • 您可能还想检查 fgets 返回的 str 的大小,因为您尝试访问 length + 3
  • 不要忽视fgets保留的newline

标签: c fopen fwrite file-management file-manipulation


【解决方案1】:

这会将输出视为文本文件(与输入相同),而不是二进制文件。我已将代码 cmets 放在适当的位置。您最严重的错误是在覆盖字符串终止符后调用strlen。反正只需要调用一次。

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

输入文件:

1 0.41 1 44
0 1.23 2 555

输出文件:

0.41 1 44 1
1.23 2 555 0

【讨论】:

  • 如果为真,OP 应该解释为什么是 1.23 2 555 0 而不是 0 1.23 2 555。我知道 OP 先需要浮点数,然后是其余的,但不清楚是否是所以
  • @Michi 他为什么要这么做?他说了他想说的话,我们不知道为什么,这无关紧要。
  • 你说得对,对不起,我没有注意这个问题:)
  • 无意复制,但my answer 建议100 和“慷慨”完全符合您的好答案。也许我应该使用像42 这样的另一个值?
  • @chux 你的答案比我简洁的答案有更多的deep thought,尤其是在讨论输出文件格式时。如您所说,最好不要尝试使用二进制输出来模拟文本文件格式。
【解决方案2】:

想想这两行

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

第一个将空字符设置为' '。第二次调用strlen(str),但str 不再具有导致未定义行为(UB)的某个空字符。


建议

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); 

以文本模式打开文件然后写入"\r\n" 也是一个问题,因为代码可以写入"\r" 然后获取"\n" 并转换为"\r\n" 导致"\r\r\n"。建议以文本模式打开文件并写入单个"\n"(将根据需要进行翻译)或以二进制模式打开文件并写入显式"\r\n"


顺便说一句:考虑在char str[15]; 中比 15 更慷慨。可能有 100 个?

【讨论】:

    猜你喜欢
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    相关资源
    最近更新 更多