在 C 中读取文件:前导零
reading a file in C: leading zeros
在我的程序中,我试图从文本文件中每行读取两个值。
它适用于我下面的代码,但是当我面对带有前导零的数字时,它会将每个零存储为一个值。
我希望能够阅读例如"007" 像普通的 "7",但我仍然希望能够读取 "0"[=33] =] 作为一个值。
任何人都可以帮助我改进我的代码或指出 what/where 它可以改进吗?
提前致谢
valuelist.txt
55 009
63 10
12 0
输出
counter: 0 | Value A: 55 Value B: 0
counter: 1 | Value A: 9 Value B: 0
counter: 2 | Value A: 9 Value B: 0
counter: 3 | Value A: 63 Value B: 0
counter: 4 | Value A: 10 Value B: 0
counter: 5 | Value A: 12 Value B: 0
counter: 6 | Value A: 0 Value B: 0
主要
int main(void) {
char name[] = "valuelist.txt";
unsigned int counter = 0;
unsigned int lines = 3;
unsigned int num;
unsigned int numtwo;
FILE* ff = fopen(name,"r");
if(ff == NULL) {
fprintf(stderr, "Error \n");
return -1;
}
char *tempp = (char*) malloc(lines + 1 );
while(fgets(tempp,lines+1,ff) != NULL){
sscanf(tempp,"%u %u",&num, &numtwo);
printf("counter: %u | ",counter);
printf("Value A: %u ",num);
printf("Value B: %u \n",numtwo);
counter++;
}
free(tempp);
tempp = NULL;
return 0;
}
您没有分配足够的 space 来阅读每一行。您将 行数 用作行的 长度 ,但它们并不相同。
您为 ttemp
分配了 4 个字节 (lines + 1
),用于在一行中读取。然而,文本的第一行有 6 个字符。所以第一次调用fgets
只读取前3个字节,即"55 "
。这就是 sscanf
解析的内容。下一次调用获取接下来的 3 个字节,即 "09\n"
并在换行符处停止读取,因此只解析出第一个数字。
由于你在循环中使用fgets
来读取行并打印内容,你实际上不需要知道有多少行。但是,您确实需要知道一行的最大长度。由于您正在读取两个十进制整数,因此 30 个字节应该足以读取整行。所以做一个那个大小的固定缓冲区:
char tempp[30];
while(fgets(tempp,sizeof(tempp),ff) != NULL){
...
在您更新的代码和数据中,问题肯定是 lines
的值对于您的使用来说太小了。您正在使用它来衡量 tempp
缓冲区需要多少 space,但这需要最大行数 width(加一个用于换行,另一个用于终结者)。相反,您给它的是一行 count,而文件的那一行只有几行。因此,fgets()
会在多个呼叫中打断您的线路。
您确实可以预先扫描文件以找到合适的宽度,然后分配那么多,但是在这里使用 fgets
而不是 fscanf
会很麻烦。对于许多问题确实有理由更喜欢它,但您的问题看起来不像其中之一。通过这样做,您可以节省大量的麻烦和代码:
unsigned num, numtwo;
while (fscanf(ff, "%u%u", &num, &numtwo) == 2) {
// update counter, print results, etc...
}
你的根本问题是你的 lines
变量。它太小了。 (应该是 "line size" 吗?)
我建议您去掉 lines
变量、tempp
变量和 malloc
调用。声明单个数组
char line[1000];
1000 个字符对于任何可以想象的输入来说应该足够长了。那么你的循环可以是
while(fgets(line, sizeof(line), ff) != NULL) { ...
您的其余代码看起来没问题。进行此更改后,您应该不会再遇到号码被奇怪地分解的问题了。
在我的程序中,我试图从文本文件中每行读取两个值。 它适用于我下面的代码,但是当我面对带有前导零的数字时,它会将每个零存储为一个值。
我希望能够阅读例如"007" 像普通的 "7",但我仍然希望能够读取 "0"[=33] =] 作为一个值。
任何人都可以帮助我改进我的代码或指出 what/where 它可以改进吗?
提前致谢
valuelist.txt
55 009
63 10
12 0
输出
counter: 0 | Value A: 55 Value B: 0
counter: 1 | Value A: 9 Value B: 0
counter: 2 | Value A: 9 Value B: 0
counter: 3 | Value A: 63 Value B: 0
counter: 4 | Value A: 10 Value B: 0
counter: 5 | Value A: 12 Value B: 0
counter: 6 | Value A: 0 Value B: 0
主要
int main(void) {
char name[] = "valuelist.txt";
unsigned int counter = 0;
unsigned int lines = 3;
unsigned int num;
unsigned int numtwo;
FILE* ff = fopen(name,"r");
if(ff == NULL) {
fprintf(stderr, "Error \n");
return -1;
}
char *tempp = (char*) malloc(lines + 1 );
while(fgets(tempp,lines+1,ff) != NULL){
sscanf(tempp,"%u %u",&num, &numtwo);
printf("counter: %u | ",counter);
printf("Value A: %u ",num);
printf("Value B: %u \n",numtwo);
counter++;
}
free(tempp);
tempp = NULL;
return 0;
}
您没有分配足够的 space 来阅读每一行。您将 行数 用作行的 长度 ,但它们并不相同。
您为 ttemp
分配了 4 个字节 (lines + 1
),用于在一行中读取。然而,文本的第一行有 6 个字符。所以第一次调用fgets
只读取前3个字节,即"55 "
。这就是 sscanf
解析的内容。下一次调用获取接下来的 3 个字节,即 "09\n"
并在换行符处停止读取,因此只解析出第一个数字。
由于你在循环中使用fgets
来读取行并打印内容,你实际上不需要知道有多少行。但是,您确实需要知道一行的最大长度。由于您正在读取两个十进制整数,因此 30 个字节应该足以读取整行。所以做一个那个大小的固定缓冲区:
char tempp[30];
while(fgets(tempp,sizeof(tempp),ff) != NULL){
...
在您更新的代码和数据中,问题肯定是 lines
的值对于您的使用来说太小了。您正在使用它来衡量 tempp
缓冲区需要多少 space,但这需要最大行数 width(加一个用于换行,另一个用于终结者)。相反,您给它的是一行 count,而文件的那一行只有几行。因此,fgets()
会在多个呼叫中打断您的线路。
您确实可以预先扫描文件以找到合适的宽度,然后分配那么多,但是在这里使用 fgets
而不是 fscanf
会很麻烦。对于许多问题确实有理由更喜欢它,但您的问题看起来不像其中之一。通过这样做,您可以节省大量的麻烦和代码:
unsigned num, numtwo;
while (fscanf(ff, "%u%u", &num, &numtwo) == 2) {
// update counter, print results, etc...
}
你的根本问题是你的 lines
变量。它太小了。 (应该是 "line size" 吗?)
我建议您去掉 lines
变量、tempp
变量和 malloc
调用。声明单个数组
char line[1000];
1000 个字符对于任何可以想象的输入来说应该足够长了。那么你的循环可以是
while(fgets(line, sizeof(line), ff) != NULL) { ...
您的其余代码看起来没问题。进行此更改后,您应该不会再遇到号码被奇怪地分解的问题了。