为什么此代码给出警告:格式'%s'期望类型为'char *',而参数2为类型'char(*)[11]'?

时间:2019-02-12 10:57:07

标签: c file

#include <stdio.h>
#include <stdlib.h>
#define RIG 5
#define COL 11

int main()
{
    FILE *fp;
    fp=fopen("swamp.txt","r");
    if((fp=fopen("swamp.txt","r"))==NULL)
    {
        puts("ERROR!");
        return -1;
    }
    char *swamp[RIG][COL];
    while(fscanf(fp,"%s",swamp)!=EOF)
    {
        printf("%s\n",swamp);
    }

    fclose(fp);

    return 0;
}

我正在处理文件,并且在fscanf内收到while的2条警告。有人可以向我解释为什么吗?

2 个答案:

答案 0 :(得分:0)

对于test.txt,如下所示:

aaaaaaa bbbbbbb ccccccc
ddddddd eeeeeee fffffff
ggggggg hhhhhhh iiiiiii
jjjjjjj kkkkkkk lllllll

您可以使用此代码获取数据(它可以处理4行3列中最多8个字符的单词):

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

int main(void)
{
    enum {
        ROWS = 4,
        COLS = 3
    };

    FILE *fp;
    char test[ROWS][COLS][9];
    int counter = ROWS * COLS;

    if ((fp = fopen("test.txt", "r")) == NULL) {
        perror("fopen()");
        return EXIT_FAILURE;
    }

    for (int i = 0; i < ROWS * COLS; i++) {
        if (fscanf(fp, "%8s", test[i / COLS][i % COLS]) == EOF) {
            counter = i;
            break;
        }
    }

    fclose(fp);

    for (int i = 0; i < counter; i++) {
        printf("%s ", test[i / COLS][i % COLS]);
        if ((i + 1) % COLS == 0) {
            printf("\n");
        }
    }

    return EXIT_SUCCESS;
}

答案 1 :(得分:0)

假设swamp.txt包含:

marsh
bog
quagmire
morass
fen

,并且您想将这些行读入程序中的数组swamp中。然后,您可以按照以下方式修改代码。请注意,这避免了两次打开文件以及其他清除操作。

#include <stdio.h>

#define RIG 5
#define COL 11

int main(void)
{
    const char filename[] = "swamp.txt";
    FILE *fp = fopen(filename, "r");
    if (fp == NULL)
    {
        fprintf(stderr, "failed to open file '%s' for reading\n", filename);
        return -1;
    }
    char swamp[RIG][COL];
    int i = 0;
    while (i < RIG && fscanf(fp, "%10s", swamp[i]) == 1)
        i++;

    fclose(fp);

    for (int j = 0; j < i; j++)
        printf("%d: %s\n", j, swamp[j]);

    return 0;
}

输出为:

0: marsh
1: bog
2: quagmire
3: morass
4: fen

请注意,该代码通过对读取的单词进行计数来防止长文件溢出。您已经检查了fopen()-很好。但是,我改进了错误消息。我认为,永远不要使用文字字符串作为文件名来调用fopen(),因为当您在打开文件时报告错误时,您需要在错误消息中输入文件名,因此您必须重复自己的操作。我固定了数组的类型,所以它是char的2D数组,而不是(未初始化的)char指针的2D数组。我安排依次将数组的每一行传递到fscanf()。我也限制了每个单词的输入长度,以防止在那里出现溢出。