C语言从文件中读取数据
Reading data from files in C
所以我有一个包含数据的大文本文件,我想重新排列它。数据每行都有整数和浮点数的组合,但我只对获取第一个整数(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);
}
这会将输出视为文本文件(与输入相同),而不是二进制文件。我在适当的地方放置了代码注释。您最严重的错误是在覆盖字符串终止符后调用 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
想想这两行
str[strlen(str)] = ' ';
str[strlen(str)+1] = temp;
第一个设置空字符为' '
。第二次调用 strlen(str)
,但 str
不再具有导致未定义行为 (UB) 的特定空字符。
改为建议
str[strcspn(str, "\r\n")] = '[=11=]'; // 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?
所以我有一个包含数据的大文本文件,我想重新排列它。数据每行都有整数和浮点数的组合,但我只对获取第一个整数(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);
}
这会将输出视为文本文件(与输入相同),而不是二进制文件。我在适当的地方放置了代码注释。您最严重的错误是在覆盖字符串终止符后调用 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
想想这两行
str[strlen(str)] = ' ';
str[strlen(str)+1] = temp;
第一个设置空字符为' '
。第二次调用 strlen(str)
,但 str
不再具有导致未定义行为 (UB) 的特定空字符。
改为建议
str[strcspn(str, "\r\n")] = '[=11=]'; // 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?