Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么可以';我在C中使用sscanf()将值读入具有简单格式字符串的简单变量吗?_C_Scanf - Fatal编程技术网

为什么可以';我在C中使用sscanf()将值读入具有简单格式字符串的简单变量吗?

为什么可以';我在C中使用sscanf()将值读入具有简单格式字符串的简单变量吗?,c,scanf,C,Scanf,我试图解析一些简单格式化的文本,并使用数字和短字符串值创建文本/数字记录的简单数据结构。我已经调试并定位了问题;这取决于sscanf()没有使用特定的格式字符串(程序中的其他格式字符串工作正常)将值读入我的变量。我创建了一个简单的文本文件来查看发生了什么 代码如下: char *idNumber = (char *)malloc(sizeof (char*)); char *partNumber = (char *)malloc(sizeof (char*)); int amountIt

我试图解析一些简单格式化的文本,并使用数字和短字符串值创建文本/数字记录的简单数据结构。我已经调试并定位了问题;这取决于sscanf()没有使用特定的格式字符串(程序中的其他格式字符串工作正常)将值读入我的变量。我创建了一个简单的文本文件来查看发生了什么

代码如下:

char *idNumber = (char *)malloc(sizeof (char*));
  char *partNumber = (char *)malloc(sizeof (char*));
  int amountItems = 0;
  double unitPrice = 0;

  char *line1 = "Govan, Guthrie (N210) AX299 x 6 $149.94";
  char *line2 = "Mustaine, Dave (N106) AX350N x 2 $63.98";
  char *line3 = "Van Halen, Edward (N1402) AV2814 x 10 $34.90";


  sscanf(line1, "%*s, %*s (%s) %s x %d $%lf",  idNumber, partNumber,
     &amountItems, &unitPrice);

  printf("%s, %s, %d, %f\n", idNumber, partNumber, amountItems,     unitPrice);


  sscanf(line2, "%*s, %*s (%s) %s x %d $%lf", idNumber, partNumber,
     &amountItems, &unitPrice);
  printf("%s, %s, %d, %lf\n", idNumber, partNumber, amountItems,     unitPrice);

  sscanf(line3, "%*s, %*s (%s) %s x %d $%lf", idNumber, partNumber,
     &amountItems, &unitPrice);
  printf("%s, %s, %d, %lf\n", idNumber, partNumber, amountItems,     unitPrice);
andrew@levin-Inspiron-3650:~/Desktop/schoolwork/project2$ ./a.out

, , 0, 0.000000
, , 0, 0.000000
, , 0, 0.000000
我对以下领域感兴趣,其余的被忽略。例如,在记录中:

“Govan,Guthrie(N210)AX299 x 6$149.94”

我希望变量中有N210、AX299、6和149.94,按顺序排列

结果如下:

char *idNumber = (char *)malloc(sizeof (char*));
  char *partNumber = (char *)malloc(sizeof (char*));
  int amountItems = 0;
  double unitPrice = 0;

  char *line1 = "Govan, Guthrie (N210) AX299 x 6 $149.94";
  char *line2 = "Mustaine, Dave (N106) AX350N x 2 $63.98";
  char *line3 = "Van Halen, Edward (N1402) AV2814 x 10 $34.90";


  sscanf(line1, "%*s, %*s (%s) %s x %d $%lf",  idNumber, partNumber,
     &amountItems, &unitPrice);

  printf("%s, %s, %d, %f\n", idNumber, partNumber, amountItems,     unitPrice);


  sscanf(line2, "%*s, %*s (%s) %s x %d $%lf", idNumber, partNumber,
     &amountItems, &unitPrice);
  printf("%s, %s, %d, %lf\n", idNumber, partNumber, amountItems,     unitPrice);

  sscanf(line3, "%*s, %*s (%s) %s x %d $%lf", idNumber, partNumber,
     &amountItems, &unitPrice);
  printf("%s, %s, %d, %lf\n", idNumber, partNumber, amountItems,     unitPrice);
andrew@levin-Inspiron-3650:~/Desktop/schoolwork/project2$ ./a.out

, , 0, 0.000000
, , 0, 0.000000
, , 0, 0.000000
预期产出为:

N210, AX299, 6, 149.94
N106, AX350N, 2, 63.98
N1402, AV2814, 10, 34.90
请分享帮助

这不是直接从我的程序中得到的代码,而是我创建的一个“助手”文件,只是为了简单地调试这个问题,而不必调用整个应用程序

以下类似代码适用于不同的格式: 记录如下:

N210 AX299 6 24.99

在以下代码中:

struct record *current = malloc(sizeof(struct record *));
current->idNumber = (char *)malloc(sizeof (char *) * 8);
current->partNumber = (char *)malloc(sizeof (char *) * 10);
sscanf(line, "%s %s %d %lf", current->idNumber, current->partNumber,
 &(current->amountItems), &(current->unitPrice));
我并不期望这段代码是一个丰富的C代码,我是一个Java开发人员,这是一个社区学院的C项目。但是你能帮我调试这个sscanf问题吗


谢谢大家!

格式字符串与参数类型不匹配。与其一个接一个地指出这里的每个错误,防止这种情况的方法是启用编译器警告。例如,如果您使用的是GCC或Clang,请将
-Wall-Wextra-Werror
添加到编译器命令中。然后,编译器将告诉您有关格式字符串不匹配的所有信息。

这里的动态分配有问题。行
char*idNumber=(char*)malloc(sizeof(char*))
为指向
char
的指针分配空间,而不是为
char
char
数组分配空间。这应该是这样的:

char *idNumber = malloc(sizeof (char) * 256);
或:

请注意,无需在C中强制转换
malloc()
的结果。第二个版本是在C中执行此操作的一种非常惯用的方法。通过避免在操作数中使用显式类型来执行
sizeof
,这在编码中更容易、更不容易出错,并且在代码生命周期内类型更改时更容易维护。但是,由于C中的
sizeof(char)
始终为1,这也可能是:

char *idNumber = malloc(256);
在分配方面吝啬是没有意义的,256为输入提供了大量空间。在尝试使用分配的内存之前,请记住始终检查分配是否成功;完成后,不要忘记释放
malloc
ed内存

但是,这并不是问题的根源。问题是格式字符串告诉
sscanf()
在第一个字符串后匹配一个逗号,但在输入中,
%*s
使用了这个逗号。没有进一步的匹配,因此
sscanf()
返回。还有一个问题是
%s)
使用输入字符串末尾的
,在格式字符串中没有要匹配的结束父项。而
%s
转换说明符读取的字符串最多为一个空白字符,因此
“Van Halen”
%*s%*s
使用,剩下
“Edward”
尝试与
(%s)
匹配。这些类型的错误是可检测的;应始终检查调用
scanf()
系列函数返回的值,以确保输入符合预期

scanset指令在这里可以起到很好的作用。此指令:
%*[^(](
告诉
scanf()
匹配任何字符,直到遇到
),抑制赋值,并在继续之前匹配
),然后
%255[^)]
指令告诉
scanf()
匹配最多255个字符,直到
)遇到
,将结果存储在一个数组中,并在最后匹配
,然后继续。请注意此处的最大宽度规格,以防止缓冲区溢出,并注意必须为
\0
终止符留出空间,该终止符将始终由
scanf()
添加

以下是一个经过修改的程序,它将按预期工作:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char *idNumber = malloc(256);
    if (idNumber == NULL) {
        perror("Allocation failure");
        exit(EXIT_FAILURE);
    }
    char *partNumber = malloc(256);
    if (idNumber == NULL) {
        perror("Allocation failure");
        exit(EXIT_FAILURE);
    }

    int amountItems = 0;
    double unitPrice = 0;

    char *line1 = "Govan, Guthrie (N210) AX299 x 6 $149.94";
    char *line2 = "Mustaine, Dave (N106) AX350N x 2 $63.98";
    char *line3 = "Van Halen, Edward (N1402) AV2814 x 10 $34.90";

    if (sscanf(line1, "%*[^(]( %255[^)]) %255s x %d $%lf",
               idNumber, partNumber, &amountItems, &unitPrice) < 4) {
        fprintf(stderr, "Input error in line1\n");
    } else {
        printf("%s, %s, %d, %f\n",
               idNumber, partNumber, amountItems, unitPrice);
    }

    if (sscanf(line2, "%*[^(]( %255[^)]) %s x %d $%lf",
               idNumber, partNumber, &amountItems, &unitPrice) < 4) {
        fprintf(stderr, "Input error in line2\n");
    } else {
        printf("%s, %s, %d, %f\n",
               idNumber, partNumber, amountItems, unitPrice);
    }

    if (sscanf(line3, "%*[^(]( %255[^)]) %s x %d $%lf",
               idNumber, partNumber, &amountItems, &unitPrice) < 4) {
        fprintf(stderr, "Input error in line3\n");
    } else {
        printf("%s, %s, %d, %f\n",
               idNumber, partNumber, amountItems, unitPrice);
    }

    free(idNumber);
    free(partNumber);

    return 0;
}

我以为你说的是“简单”,但后来我看到了输入记录和想要的和不想要的位,结果是“不简单”如果你
malloc
某个东西,你必须
释放它。他们发明了函数,你用它来避免把同样棘手的代码写三次。常用的材料放在函数体中,变量放在参数中id bowling,david hoelzer。你能帮助解决sscanf问题吗?D.bowling:我已经修复了它,在gdb中,值仍然显示为没有被sscanf()填充,甚至在printf问题之外,我想我已经修复了它(在OP中被新代码替换)谢谢!我已经更改了代码以符合警告,并且代码现在已在原始帖子中编辑和替换…除了不使用args to main()之外,现在没有任何警告。我仍然收到意外的输出!您能帮助我吗?@AndrewLevin:修复所有错误!
sscanf(第1行,%*s,%*s(%s)%s x%d$%lf“,idNumber,partNumber,&amountItems,&unitPrice);
如果使用我告诉过你的选项,将不会编译。我编辑了上面的代码,它确实编译了&没有给出错误。我使用了一个简单的printf来打印argc的值和argv的一个元素。编译时没有警告或错误,仍然是“空的” output@AndrewLevin:好的,现在您的错误是scanf()的工作方式与您想象的不一样。有关如何使其停止在分隔符处,请参阅:-您需要类似于
%*[^,],
sscanf(line1,“%*[^(]([^)])%s%*[^x]x%d%*[^$]$%f”、idNumber、partNumber、&amountItems和unitPrice的内容;
您是否完成了tr