将整数读入C中的数组
Read integers into an array in C
我正在尝试将整数文本文件读入 C 中的数组。
我的文本文件如下所示:(12 numbers/line)
5713 6936 8764 6702 8535 8654 8710 8332 4948 7627 5472 5311
7331 8719 6135 6672 5786 7113 5292 6923 5683 7020 8595 8606
6837 7003 7415 8372 8429 5726 8323 6442 8672 6488 6932 5884
6811 7785 7189 5531 6323 8561 8283 5114 6669 7217 8307 6599
6961 8695 6026 5580 6010 4954 8725 4955 5532 7736 5372 8712
8343 5375 5931 6449 8223 5844 5931 5307 5436 6405 8599 6302
8617 8222 5985 8216 5044 5259 6523 7526 8702 5878 7559 5366
5362 7393 6633 8781 6289 6470 5342 7278 5348 8677 5779 5763
5718 8678 6406 8774 5931 7324 6819 6393 5027 7545 8385 8795
8277 8059 6362 6980 5899 5828 6707 7149 5621 7287 5958 6506
6517 5710 5504 7070 8797 6840 7112 6063 7014 5419 7514 7431
实际文件共有1000个号码
目前,我正在使用以下代码:
int main(void){
FILE *my_file;
my_file = fopen("seals.txt", "r");
size_t size = word_conter(my_file);
int weight = 0;
int seals[size];
int i;
for(i = 0; i < size; i++){
if(fscanf(my_file, "%1d", &weight) == 1)
seals[i] = weight;
else break;
}
for(i = 0; i < size; i++){
printf("%d\t %d\n", i, seals[i]);
}
fclose(my_file);
return 0;
}
编辑:这里是 word_counter
:
size_t word_conter(FILE *my_file){
if(my_file == NULL){
perror("Error in file");
exit(1);
}
size_t counter = 0, in_word = 0;
char ch;
while((ch = fgetc(my_file)) != EOF){
if(ch == ' ' || ch == '\n' || ch == '\t' || ch == '[=12=]'){
if(in_word){
in_word = 0;
counter++;
}
}
else in_word = 1;
}
return counter;
}
不幸的是,我的输出是:
0 245589760
1 1
2 1
3 0
4 -497513808
5 32766
6 245022469
7 1
8 -497513808
9 32766
10 245022268
11 1
12 1
13 0
14 224894352
15 1
16 -497513744
17 32766
18 244994643
19 1
20 245557328
21 1
22 224894352
23 1
24 224879992
25 1
26 0
27 0
28 245584536
29 1
30 245616784
31 1
32 -497513712
33 32766
34 245024298
35 1
36 245557328
37 1
38 -799666472
39 22978
40 -497510096
以此类推直到999。
我都试过:
fscanf(my_file, "%1d", &weight)
和 fscanf(my_file, "%d", &weight)
但两者都没有用。我已经阅读了有关 fscanf 的手册,但仍然无法正确理解。
如有任何帮助,我们将不胜感激!
第二次编辑:
我使用了 rewind()
并且成功了!
尝试将 if(fscanf(my_file, "%1d", &weight) == 1)
替换为 if(fscanf(my_file, "%d", &weight) != EOF)
简而言之,这是由于连续两次读取数据文件而没有调用rewind()
。
造成的
问题出现在fscanf()
没有倒带的情况下第二次读取文件。 (首先读取在 word_conter()
函数中):
if(fscanf(my_file, "%d", &weight) == 1)//2nd read on one file descriptor
seals[i] = weight;//program flow never gets here
else break;
这导致执行流程直接跳转到else break;
,然后继续在printf()
上循环并输出未初始化的数组:int seals[size];
此外,函数 word_conter
容易受到正在读取的文件中可能存在的各种数据格式不一致的影响。建议在调试器中单步执行代码以准确描述这可能是如何导致问题的。
我的建议是在 word_counter
中调用 fopen()
和 fclose
一次,然后在主函数中再次调用它们。 size_t word_conter(FILE *my_file)
的重构版本支持这种方法。 (按照评论中提到的,编写以容纳每行包含 12 个数字的文件):
size_t word_counter(char *filename)
{
char line[260] = {0};
char *tok = NULL;
int count = 0;
FILE *fp = fopen(filename, "r");
if(fp)
{
while(fgets(line, sizeof(line), fp))
{
tok = strtok(line, " \n");
while(tok)
{
count++;
tok = strtok(NULL, " \n");
}
memset(line, 0, sizeof(line));
}
fclose(fp);
}
return count;
}
主要调用为:
size_t size = word_counter("seals.txt");
还有一个使用错误的例子format specifier can invoke undefined behavior
对于:
int weight = 0;
正确的格式说明符是 "%d"
。要么改变:
if(fscanf(my_file, "%1d", &weight) == 1)
至:
if(fscanf(my_file, "%d", &weight) == 1)
或更改:
int weight = 0;
int seals[size];
至:
long weight = 0;
long seals[size];
(%ld
仅用于 long
。)
解决其中的每一个问题都可能解决您所遇到的问题。 (但由于word_conter()
没有详细展示,可能还有其他问题。)
Word 计数器在边界情况下出现混乱。
寻找从 space 到非 space 的过渡。不要忘记 rewind()
.
size_t counter = 0;
bool in_word = false;
// char ch;
int ch;
while((ch = fgetc(my_file)) != EOF){
if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '[=10=]') { // better: if (isspace(ch)) {
in_word = false;
} else {
if (!in_word) counter++;
in_word = true;
}
}
rewind(my_file); // reset to the beginning
return counter;
更好的是,只需使用相同格式浏览文件两次。
size_t counter = 0;
while (fscanf(my_file, "%d", &weight) == 1) {
counter++;
}
rewind(my_file); // reset to the beginning
我正在尝试将整数文本文件读入 C 中的数组。
我的文本文件如下所示:(12 numbers/line)
5713 6936 8764 6702 8535 8654 8710 8332 4948 7627 5472 5311
7331 8719 6135 6672 5786 7113 5292 6923 5683 7020 8595 8606
6837 7003 7415 8372 8429 5726 8323 6442 8672 6488 6932 5884
6811 7785 7189 5531 6323 8561 8283 5114 6669 7217 8307 6599
6961 8695 6026 5580 6010 4954 8725 4955 5532 7736 5372 8712
8343 5375 5931 6449 8223 5844 5931 5307 5436 6405 8599 6302
8617 8222 5985 8216 5044 5259 6523 7526 8702 5878 7559 5366
5362 7393 6633 8781 6289 6470 5342 7278 5348 8677 5779 5763
5718 8678 6406 8774 5931 7324 6819 6393 5027 7545 8385 8795
8277 8059 6362 6980 5899 5828 6707 7149 5621 7287 5958 6506
6517 5710 5504 7070 8797 6840 7112 6063 7014 5419 7514 7431
实际文件共有1000个号码
目前,我正在使用以下代码:
int main(void){
FILE *my_file;
my_file = fopen("seals.txt", "r");
size_t size = word_conter(my_file);
int weight = 0;
int seals[size];
int i;
for(i = 0; i < size; i++){
if(fscanf(my_file, "%1d", &weight) == 1)
seals[i] = weight;
else break;
}
for(i = 0; i < size; i++){
printf("%d\t %d\n", i, seals[i]);
}
fclose(my_file);
return 0;
}
编辑:这里是 word_counter
:
size_t word_conter(FILE *my_file){
if(my_file == NULL){
perror("Error in file");
exit(1);
}
size_t counter = 0, in_word = 0;
char ch;
while((ch = fgetc(my_file)) != EOF){
if(ch == ' ' || ch == '\n' || ch == '\t' || ch == '[=12=]'){
if(in_word){
in_word = 0;
counter++;
}
}
else in_word = 1;
}
return counter;
}
不幸的是,我的输出是:
0 245589760
1 1
2 1
3 0
4 -497513808
5 32766
6 245022469
7 1
8 -497513808
9 32766
10 245022268
11 1
12 1
13 0
14 224894352
15 1
16 -497513744
17 32766
18 244994643
19 1
20 245557328
21 1
22 224894352
23 1
24 224879992
25 1
26 0
27 0
28 245584536
29 1
30 245616784
31 1
32 -497513712
33 32766
34 245024298
35 1
36 245557328
37 1
38 -799666472
39 22978
40 -497510096
以此类推直到999。
我都试过:
fscanf(my_file, "%1d", &weight)
和 fscanf(my_file, "%d", &weight)
但两者都没有用。我已经阅读了有关 fscanf 的手册,但仍然无法正确理解。
如有任何帮助,我们将不胜感激!
第二次编辑:
我使用了 rewind()
并且成功了!
尝试将 if(fscanf(my_file, "%1d", &weight) == 1)
替换为 if(fscanf(my_file, "%d", &weight) != EOF)
简而言之,这是由于连续两次读取数据文件而没有调用rewind()
。
问题出现在fscanf()
没有倒带的情况下第二次读取文件。 (首先读取在 word_conter()
函数中):
if(fscanf(my_file, "%d", &weight) == 1)//2nd read on one file descriptor
seals[i] = weight;//program flow never gets here
else break;
这导致执行流程直接跳转到else break;
,然后继续在printf()
上循环并输出未初始化的数组:int seals[size];
此外,函数 word_conter
容易受到正在读取的文件中可能存在的各种数据格式不一致的影响。建议在调试器中单步执行代码以准确描述这可能是如何导致问题的。
我的建议是在 word_counter
中调用 fopen()
和 fclose
一次,然后在主函数中再次调用它们。 size_t word_conter(FILE *my_file)
的重构版本支持这种方法。 (按照评论中提到的,编写以容纳每行包含 12 个数字的文件):
size_t word_counter(char *filename)
{
char line[260] = {0};
char *tok = NULL;
int count = 0;
FILE *fp = fopen(filename, "r");
if(fp)
{
while(fgets(line, sizeof(line), fp))
{
tok = strtok(line, " \n");
while(tok)
{
count++;
tok = strtok(NULL, " \n");
}
memset(line, 0, sizeof(line));
}
fclose(fp);
}
return count;
}
主要调用为:
size_t size = word_counter("seals.txt");
还有一个使用错误的例子format specifier can invoke undefined behavior
对于:
int weight = 0;
正确的格式说明符是 "%d"
。要么改变:
if(fscanf(my_file, "%1d", &weight) == 1)
至:
if(fscanf(my_file, "%d", &weight) == 1)
或更改:
int weight = 0;
int seals[size];
至:
long weight = 0;
long seals[size];
(%ld
仅用于 long
。)
解决其中的每一个问题都可能解决您所遇到的问题。 (但由于word_conter()
没有详细展示,可能还有其他问题。)
Word 计数器在边界情况下出现混乱。
寻找从 space 到非 space 的过渡。不要忘记 rewind()
.
size_t counter = 0;
bool in_word = false;
// char ch;
int ch;
while((ch = fgetc(my_file)) != EOF){
if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '[=10=]') { // better: if (isspace(ch)) {
in_word = false;
} else {
if (!in_word) counter++;
in_word = true;
}
}
rewind(my_file); // reset to the beginning
return counter;
更好的是,只需使用相同格式浏览文件两次。
size_t counter = 0;
while (fscanf(my_file, "%d", &weight) == 1) {
counter++;
}
rewind(my_file); // reset to the beginning