C错误:格式'%s'期望类型' char *'的参数,但参数2的类型为' char **'

时间:2016-01-30 17:05:48

标签: c

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

void convert(int type, double amount, double rate);
int get_type(char* string);

void convert(int type, double amount, double rate) {
printf("%.2f %s is %.2f %s\n", amount, type == 1 ? "dollars" : "euros",amount * rate, type == 1 ? "euros" : "dollars");
                  }

int get_type(char* string) {
int i, c;
for (i = 0, c = string[0]; c != '\0'; c = string[i]) {
    if (c >= 'A' && c <= 'Z') {
        string[i] -= 'A' - 'a';
    }
}
return !strcmp(string, "dollar") ? 1 : !strcmp(string, "euro") ? 2 : 0;
         }

    int main(int argc, char** argv) {
    assert(argc != 2 || argc ==4);
if (argc == 4) {
    int type = get_type(argv[1]);
    if (type == 0) {
        printf("%s is an invalid currency type. Use dollar or euro.\n", argv[1]);
        return 1;
    }
    convert(type, atof(argv[2]), atof(argv[3]));
}

if (argc == 2) {
    FILE* fd;
    fd = fopen(argv[1], "r");
    if (fd == NULL) {
        printf("Could not open %s\n", argv[1]);
        return 1;
    }
char* typestring = (char*)malloc(16 * sizeof(char));

    double amount, rate;
    int matches, type;

    while (!feof(fd)) {
        matches = fscanf(fd, "%s %lf %lf\n", &typestring, &amount, &rate);
        if (matches != 3) {
            printf("Line was not formed correctly.\n");
            continue;
        }
        type = get_type(typestring);
        if (type == 0) {
            printf("%s is an invalid currency type. Use dollar or euro.\n", typestring);
            continue;
        }
        convert(type, amount, rate);
    }
    free(typestring);
}


if (argc == 2 && argc != 4) {
    printf("Usage:\n\tmoney-exchange [dollar|euro type] [double amount] [double rate]\n");
    printf("\tmoney-exchange [FILE]\n");
    printf("Examples:\n\tmoney-exchange dollar 10.50 0.92\n");
    printf("\tmoney-exchange euro 5.99 1.09\n");
    printf("\tmoney-exchange prices.txt\n");
    return 1;
}
return 0;
     }

在功能&#39;主要&#39;: 47:4:警告:格式&#39;%s&#39;期望类型&#39; char *&#39;的参数,但参数3的类型为&#39; char **&#39; [-Wformat =]     matches = fscanf(fd,&#34;%s%lf%lf \ n&#34;,&amp; typestring,&amp; amount,&amp; rate);

为什么会这样?

2 个答案:

答案 0 :(得分:0)

%s格式说明符要求相应的参数是指向字符数组的指针,而不是字符串,并且您有责任分配足够大的字符数组。因此,相应的参数必须为typestring,而不是typestring

您已将typestring分配为最多15个字符的足够大的数组,但代码中没有任何内容可以验证该文件不包含更大的字符串,在这种情况下您将最终内存损坏和未定义的行为。

因此,scanf函数族通常不是解析不受信任输入的最强大或推荐的方法。当你正在学习C和C ++时,重要的是要理解这个主题,以避免在你未来的职业生涯中犯下更为严重的错误。

答案 1 :(得分:0)

typestring是一个char *,它是%s说明符的用途,但是你提供&amp; typestring,并且包括&amp;;这使它成为一个char **。传递类型字符串没有&amp;并且你的编译器错误应该会消失,但是关于确保足够大小的答案在这里是相关的,所以请检查一下!