使用 fscanf 读取 C 中的坐标时出现问题
Trouble using fscanf to read coordinates in C
我知道有人问过类似的问题,但 none 似乎解决了我的问题。当我 运行 我的代码时,我得到 Segmentation fault (core dumped)
。
"data.dat" 中的第一行是文件中点的总数,接下来的几行是点坐标(二维)。我正在使用 fgets
来阅读第一行,然后我正在使用 fscanf
来阅读下一行。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
FILE *fp;
fp = fopen("data.dat","r");
if (fp == NULL) {
perror("Error");
}
int number;
char str[3];
fgets(str, 3, fp);
number = atoi(str); // number of points to read from the file
printf("number of lines: %d\n", number);
// defining matrix to hold points
float *P = (float *) malloc(sizeof(float)*2*number);
int i = 0;
while(i < number){
int ret = fscanf(fp, "%f%f", P[i*number + 1], P[i*number + 2]);
printf("%f %f", P[i*number + 1], P[i*number + 2]);
if (ret == 2){
i++;
}
}
fclose(fp);
return 0;
}
编译它没有给我任何错误,但它确实给了我以下警告:
polynom.c: In function ‘main’:
polynom.c:32:24: warning: format ‘%f’ expects argument of type ‘float*’,but argument 3 has type ‘double’ [-Wformat=]
int ret = fscanf(fp, "%f%f", P[i*number + 1], P[i*number + 2]);
^
polynom.c:32:24: warning: format ‘%f’ expects argument of type ‘float *’, but argument 4 has type ‘double’ [-Wformat=]
我不太明白,因为我确实将参数 3 定义为浮点数。
我 运行 带有命令行变量的代码所以分段错误不是因为那个。
你需要使用 "%lf"
说明符,如果你的变量是 double
,你必须将变量的地址传递给 scanf()
而不是变量本身,像这样
double value;
if (scanf("%lf", &value) == 1)
{ /* ^ ^ */
/* | the address of operator. */
/* the correct speficier for `double' */
fprintf(stdout, "%lf\n", value);
}
应该是
while (2 == fscanf(fp, "%f%f", &P[i], &P[i+1]) {
i += 2;
if (i >= number*2)
break;
}
很好地回答了主要问题。
以下是附加点。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// Check argc
if (argc < 1) Print_Error_And Quit();
int n = atoi(argv[1]);
FILE *fp;
fp = fopen("data.dat","r");
if (fp == NULL) {
perror("Error");
}
int number;
char str[3];
// avoid naked magic numbers
// fgets(str, 3, fp);
fgets(str, sizeof str, fp);
number = atoi(str); // number of points to read from the file
printf("number of lines: %d\n", number);
// defining matrix to hold points
// No need for cast, avoid mis-match type/variable
// float *P = (float *) malloc(sizeof(float)*2*number);
float *P = malloc(2*number * sizeof *P);
int i = 0;
while(i < number){
// int ret = fscanf(fp, "%f%f", P[i*number + 1], P[i*number + 2]);
// reform
int ret = fscanf(fp, "%f%f", &P[2*i], &P[2*i + 1]);
// printf("%f %f", P[i*number + 1], P[i*number + 2]);
printf("%f %f ", P[2*i], P[2*i + 1]);
if (ret == 2){
i++;
}
else {
Likely_Should_Exit_Loop();
}
}
fclose(fp);
return 0;
}
malloc 行返回一个指针,该指针指向一个足以容纳 'number*2' 浮点数的区域。听起来不错,但实际上并不能正常工作,因为一个浮点数和下一个浮点数之间没有区别。
建议
struct twoFloat
{
float float1;
float float2;
};
然后
struct twoFloat* P = malloc(sizeof(struct twoFloat)*number);
if ( NULL == P ) { // handle error and exit }
// implied else, malloc successful
....
然后
int ret = fscanf(fp, "%f%f", &P[i].float1, &P[i].float2);
if (ret != 2) { // handle error and exit }
// implied else, fscanf successful
printf("%f %f", P[i].float1, P[i].float2);
i++;
我知道有人问过类似的问题,但 none 似乎解决了我的问题。当我 运行 我的代码时,我得到 Segmentation fault (core dumped)
。
"data.dat" 中的第一行是文件中点的总数,接下来的几行是点坐标(二维)。我正在使用 fgets
来阅读第一行,然后我正在使用 fscanf
来阅读下一行。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
FILE *fp;
fp = fopen("data.dat","r");
if (fp == NULL) {
perror("Error");
}
int number;
char str[3];
fgets(str, 3, fp);
number = atoi(str); // number of points to read from the file
printf("number of lines: %d\n", number);
// defining matrix to hold points
float *P = (float *) malloc(sizeof(float)*2*number);
int i = 0;
while(i < number){
int ret = fscanf(fp, "%f%f", P[i*number + 1], P[i*number + 2]);
printf("%f %f", P[i*number + 1], P[i*number + 2]);
if (ret == 2){
i++;
}
}
fclose(fp);
return 0;
}
编译它没有给我任何错误,但它确实给了我以下警告:
polynom.c: In function ‘main’:
polynom.c:32:24: warning: format ‘%f’ expects argument of type ‘float*’,but argument 3 has type ‘double’ [-Wformat=]
int ret = fscanf(fp, "%f%f", P[i*number + 1], P[i*number + 2]);
^
polynom.c:32:24: warning: format ‘%f’ expects argument of type ‘float *’, but argument 4 has type ‘double’ [-Wformat=]
我不太明白,因为我确实将参数 3 定义为浮点数。
我 运行 带有命令行变量的代码所以分段错误不是因为那个。
你需要使用 "%lf"
说明符,如果你的变量是 double
,你必须将变量的地址传递给 scanf()
而不是变量本身,像这样
double value;
if (scanf("%lf", &value) == 1)
{ /* ^ ^ */
/* | the address of operator. */
/* the correct speficier for `double' */
fprintf(stdout, "%lf\n", value);
}
应该是
while (2 == fscanf(fp, "%f%f", &P[i], &P[i+1]) {
i += 2;
if (i >= number*2)
break;
}
以下是附加点。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// Check argc
if (argc < 1) Print_Error_And Quit();
int n = atoi(argv[1]);
FILE *fp;
fp = fopen("data.dat","r");
if (fp == NULL) {
perror("Error");
}
int number;
char str[3];
// avoid naked magic numbers
// fgets(str, 3, fp);
fgets(str, sizeof str, fp);
number = atoi(str); // number of points to read from the file
printf("number of lines: %d\n", number);
// defining matrix to hold points
// No need for cast, avoid mis-match type/variable
// float *P = (float *) malloc(sizeof(float)*2*number);
float *P = malloc(2*number * sizeof *P);
int i = 0;
while(i < number){
// int ret = fscanf(fp, "%f%f", P[i*number + 1], P[i*number + 2]);
// reform
int ret = fscanf(fp, "%f%f", &P[2*i], &P[2*i + 1]);
// printf("%f %f", P[i*number + 1], P[i*number + 2]);
printf("%f %f ", P[2*i], P[2*i + 1]);
if (ret == 2){
i++;
}
else {
Likely_Should_Exit_Loop();
}
}
fclose(fp);
return 0;
}
malloc 行返回一个指针,该指针指向一个足以容纳 'number*2' 浮点数的区域。听起来不错,但实际上并不能正常工作,因为一个浮点数和下一个浮点数之间没有区别。
建议
struct twoFloat
{
float float1;
float float2;
};
然后
struct twoFloat* P = malloc(sizeof(struct twoFloat)*number);
if ( NULL == P ) { // handle error and exit }
// implied else, malloc successful
....
然后
int ret = fscanf(fp, "%f%f", &P[i].float1, &P[i].float2);
if (ret != 2) { // handle error and exit }
// implied else, fscanf successful
printf("%f %f", P[i].float1, P[i].float2);
i++;