将文件中的数字读入数组
Reading numbers from a file into an array
我想使用 fgetc() 命令从文件中读取中间带有空格的 3 位数字,并将它们放入一个数组中,该数组当前不起作用,因为生成的数组在它。我究竟做错了什么? (我使用了一个包含“107 313 052 614”的文件,导致输出“5435 5641 5380 5942”)
我的代码:
#include<stdio.h>
#include<stdlib.h>
void print_array(int* arrayp, int lengthp){
int i;
for(i=0;i<lengthp;i++){
printf("%i ", arrayp[i]);
}
return;
}
int main(){
int length=1;
int i;
FILE *fp1;
fp1 = fopen("durations.txt", "r");
fgetc(fp1);fgetc(fp1);fgetc(fp1);
while(fgetc(fp1)!=EOF){
length++;
fgetc(fp1);
fgetc(fp1);
fgetc(fp1);
}
fclose(fp1);
int* list = (int*) malloc(sizeof(int)*length);
FILE *fp2;
fp2 = fopen("durations.txt", "r");
for(i=0;i<length;i++){
list[i]=0;
list[i]+=100*(fgetc(fp2));
list[i]+=10*(fgetc(fp2));
list[i]+=(fgetc(fp2));
fgetc(fp2);
}
fclose(fp2);
print_array(list, length);
return 0;
}
"readable" 文件中用于存储数字的字符不是 "numbers"。最流行的编码是 ascii character encoding,例如。 1
数字用十进制数字 49 表示。
因为ascii编码中的0,1,2 ... 9位是按递增顺序编码的,所以只需减去48(即'0'
字符)即可将数字字符转换为机器格式就 - '0'
.
将循环更改为:
for(i=0;i<length;i++){
list[i]=0;
list[i]+=100*(fgetc(fp2) - '0');
list[i]+=10*(fgetc(fp2) - '0');
list[i]+=(fgetc(fp2) - '0');
fgetc(fp2);
}
这也解释了程序的当前输出。如果您不从数字中减去 '0'
,那么例如 107
您会得到:
100 * '1' + 10 * '0' + '7' =
100 * 49 + 10 * 48 + 55 =
5435
49
、48
和55
是ascii[=36]中数字1
、0
和7
的十进制值=].
问题是您正在读取每个数字的(可能)ASCII
值并假设这是该数字的值。你需要从每个值中减去零字符的值,像这样:
for (i = 0; i < length; i++) {
list[i] = 0;
list[i] += 100 * (fgetc(fp2)-'0');
list[i] += 10 * (fgetc(fp2)-'0');
list[i] += (fgetc(fp2)-'0');
fgetc(fp2);
}
即使您的系统不使用 ASCII
编码,这也能正常工作。
将数字读入 cstrings 然后使用 stdlib 函数 atoi 在加载到 int 数组之前将每个字符串转换为数字可能更简单:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//open the file for reading with error checking:
FILE* fp;
char c = '0';
int length = 0;
fp = fopen("durations.txt", "r");
if (fp == NULL) {
printf("Could not open file\n");
return 0;
}
//count the number of lines in a EOF-terminated string w/o newlines
for (c = fgetc(fp); c != EOF; c = fgetc(fp)) {
if (c == ' ') {
length += 1;
}
}
rewind(fp); //go back to file end w/o needing close/open
//Then, assuming only spaces are between numbers (so length = length + 1)
char buffer[4];
int* lst = (int*) malloc(sizeof(int)*length);
for (int i = 0; i < length + 1; i++) {
fscanf(fp, "%s", buffer); //stops at spaces
lst[i] = atoi(buffer);
}
//close the file with error checking
int check = fclose(fp);
if (check != 0) {
printf("File close failed");
return 0;
}
for (int i = 0; i < length + 1; i++) { //print result
printf("%d\n", lst[i]);
}
free(lst); //clean up memory after use
lst = NULL;
return 0;
}
我想使用 fgetc() 命令从文件中读取中间带有空格的 3 位数字,并将它们放入一个数组中,该数组当前不起作用,因为生成的数组在它。我究竟做错了什么? (我使用了一个包含“107 313 052 614”的文件,导致输出“5435 5641 5380 5942”)
我的代码:
#include<stdio.h>
#include<stdlib.h>
void print_array(int* arrayp, int lengthp){
int i;
for(i=0;i<lengthp;i++){
printf("%i ", arrayp[i]);
}
return;
}
int main(){
int length=1;
int i;
FILE *fp1;
fp1 = fopen("durations.txt", "r");
fgetc(fp1);fgetc(fp1);fgetc(fp1);
while(fgetc(fp1)!=EOF){
length++;
fgetc(fp1);
fgetc(fp1);
fgetc(fp1);
}
fclose(fp1);
int* list = (int*) malloc(sizeof(int)*length);
FILE *fp2;
fp2 = fopen("durations.txt", "r");
for(i=0;i<length;i++){
list[i]=0;
list[i]+=100*(fgetc(fp2));
list[i]+=10*(fgetc(fp2));
list[i]+=(fgetc(fp2));
fgetc(fp2);
}
fclose(fp2);
print_array(list, length);
return 0;
}
"readable" 文件中用于存储数字的字符不是 "numbers"。最流行的编码是 ascii character encoding,例如。 1
数字用十进制数字 49 表示。
因为ascii编码中的0,1,2 ... 9位是按递增顺序编码的,所以只需减去48(即'0'
字符)即可将数字字符转换为机器格式就 - '0'
.
将循环更改为:
for(i=0;i<length;i++){
list[i]=0;
list[i]+=100*(fgetc(fp2) - '0');
list[i]+=10*(fgetc(fp2) - '0');
list[i]+=(fgetc(fp2) - '0');
fgetc(fp2);
}
这也解释了程序的当前输出。如果您不从数字中减去 '0'
,那么例如 107
您会得到:
100 * '1' + 10 * '0' + '7' =
100 * 49 + 10 * 48 + 55 =
5435
49
、48
和55
是ascii[=36]中数字1
、0
和7
的十进制值=].
问题是您正在读取每个数字的(可能)ASCII
值并假设这是该数字的值。你需要从每个值中减去零字符的值,像这样:
for (i = 0; i < length; i++) {
list[i] = 0;
list[i] += 100 * (fgetc(fp2)-'0');
list[i] += 10 * (fgetc(fp2)-'0');
list[i] += (fgetc(fp2)-'0');
fgetc(fp2);
}
即使您的系统不使用 ASCII
编码,这也能正常工作。
将数字读入 cstrings 然后使用 stdlib 函数 atoi 在加载到 int 数组之前将每个字符串转换为数字可能更简单:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//open the file for reading with error checking:
FILE* fp;
char c = '0';
int length = 0;
fp = fopen("durations.txt", "r");
if (fp == NULL) {
printf("Could not open file\n");
return 0;
}
//count the number of lines in a EOF-terminated string w/o newlines
for (c = fgetc(fp); c != EOF; c = fgetc(fp)) {
if (c == ' ') {
length += 1;
}
}
rewind(fp); //go back to file end w/o needing close/open
//Then, assuming only spaces are between numbers (so length = length + 1)
char buffer[4];
int* lst = (int*) malloc(sizeof(int)*length);
for (int i = 0; i < length + 1; i++) {
fscanf(fp, "%s", buffer); //stops at spaces
lst[i] = atoi(buffer);
}
//close the file with error checking
int check = fclose(fp);
if (check != 0) {
printf("File close failed");
return 0;
}
for (int i = 0; i < length + 1; i++) { //print result
printf("%d\n", lst[i]);
}
free(lst); //clean up memory after use
lst = NULL;
return 0;
}