繁体   English   中英

C编程fscanf分段错误

[英]C programming fscanf segmentation error

我试图从具有逗号分隔值的文件中读取(第5个字段应该只有r / b / n,第6个字段是y / n:

531,A,10,10,b,n,96.00,100.00
531,B,15,15,b,n,144.00,0.00
531,C,20,20,b,n,192.00,0.00
533,A,11,11,r,n,123.20,100.00
533,B,22,22,r,n,246.40,0.00

我有以下fscanf代码块来逐行解析文件并将值存储在我稍后更改/输出的数组中。

while(fscanf(data, "%4[0-9],%[A-Z],%3[0-9],%3[0-9],[prb],[yn],%d,%d\n", &house[i], room[i], &length[i], &width[i], paintcode[i], ceilingcode[i], &cost[i], &setupcost[i]) != EOF) {
   printf("%d,%c,%d,%d,%c,%c,%.2lf,%.2lf\n", &house[i], room[i], &length[i], &width[i], paintcode[i], ceilingcode[i], &cost[i], &setupcost[i]);
   i++;
}

不幸的是,我收到了分段错误,它发生在这一行。 我已经改变并测试了大约一个小时,我很确定我做对了,除非我遗漏了一些东西。 任何帮助将不胜感激,完整的主要功能粘贴在下面。

main() {
   FILE *data;
   int house[200];
   char room[200];
   int length[200];
   int width[200];
   char paintcode[200];
   char ceilingcode[200];
   double cost[200];
   double setupcost[200];
   char line;
   int MAX_BUFF = 200;
   char x[200];
   double price[100];
   int i = 0, num_records = 0;

   data = fopen("quotes.data","r");
   if(data == NULL){
      printf("Error: file can't be open..\n");
   } else {
      while(fscanf(data, "%4[0-9],%[A-Z],%3[0-9],%3[0-9],[prb],[yn],%d,%d\n", &house[i], room[i], &length[i], &width[i], paintcode[i], ceilingcode[i], &cost[i], &setupcost[i]) != EOF) {
         printf("%d,%c,%d,%d,%c,%c,%.2lf,%.2lf\n", &house[i], room[i], &length[i], &width[i], paintcode[i], ceilingcode[i], &cost[i], &setupcost[i]);
         i++;
      }
      fclose(data);

这里有很多问题。

首先,如果读取失败而没有获得任何输入值,则scanf系列将仅返回EOF 如果您成功获得了一些但不是全部,您将获得成功扫描的数量的计数(包括您获得所有数字的情况)。

您还需要传递要填充的变量的地址 ,这些变量尚未对所有变量进行填充。

此外,像%4[0-9]这样的格式说明符将读取字符,而不是单个整数,因此它需要字符缓冲区,而不是您需要的整数地址。 如果要填充整数,则需要使用%4d

%[AZ]前面,这些实际上创建了一个以null结尾的字符串,因此您需要为其提供空间。

还要确保您可以读取行末尾的浮点值而不是整数,并且您缺少一些%格式字符。

最后, printf只需要字符串参数的地址。

以下程序使用您的输入文件以简化形式(无数组)显示此操作:

#include <stdio.h>

int main (void) {
    FILE *data;
    char room[2], paintcode[2], ceilingcode[2];
    int house, length, width;
    double cost, setupcost;

    data = fopen("quotes.data","r");
    if (data == NULL) {
        printf("Error: file can't be opened.\n");
    } else {
        while (fscanf (data, "%4d,%[A-Z],%3d,%3d,%[prb],%[yn],%lf,%lf\n",
            &house, room, &length, &width, paintcode, ceilingcode, &cost,
            &setupcost) == 8)
        {
            printf ("%d,%c,%d,%d,%c,%c,%.2lf,%.2lf\n",
                house, *room, length, width, *paintcode, *ceilingcode,
                cost, setupcost);
        }
    }
    fclose(data);
    return 0;
}

只有在将参数传递给fscanf时才需要获取地址(如&house[i] )。 fprintf整数和单字符参数按值传递:

printf("%d,%c,%d,%d,%c,%c,%.2lf,%.2lf\n", house[i], room[i], length[i], width[i], paintcode[i], ceilingcode[i], cost[i], setupcost[i]);

另一方面,调用fscanf需要指针。 由于您将单个字符扫描为字符而不是字符串,因此您应该传递房间地址,paintcode等。

正确检查scanf的返回值

RETURN VALUE
   These functions return the number of input items successfully matched and 
   assigned,  which  can  be fewer than provided for, or even zero in the event
   of an early matching failure.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM