Почему этот код выдает предупреждение: формат "% s" ожидает тип "char *", а аргумент 2 имеет тип "char (*) [11]"? - PullRequest
0 голосов
/ 12 февраля 2019
#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;
}

Я работаю с файлами и получаю 2 предупреждения для fscanf внутри while.Может кто-нибудь объяснить мне, почему?

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Предположим, 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, а не двумерный массив (неинициализированных) char указателей.Я организовал передачу каждой строки массива в fscanf() по очереди.Я также ограничил длину ввода для каждого слова, чтобы избежать переполнения.

0 голосов
/ 12 февраля 2019

Для test.txt, как показано ниже:

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

Вы можете получить данные с помощью этого кода (он может обрабатывать слова длиной до 8 символов в 4 строках и 3 столбцах):

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...