Ошибка сегментации при записи массива символов в файл размером C - PullRequest
0 голосов
/ 27 мая 2020

Когда я запускаю следующий код, я получаю «Ошибка сегментации» в fprintf(outfile, "%s", inputline[j]);.

Я не могу понять, в чем причина ошибки. Я относительно новичок в C, может ли кто-нибудь помочь мне устранить ошибку?

void test(char *inputline) {
    FILE *outfile = fopen("results.txt", "w");   
    if (!outfile) {
        perror("Error while opening file: ");
    } else {
        for (int j = 0; j < 20; ++j) { // I only want to be write the first 20 characters to the file that is why I have the iteration till only 20 and added [j], is that correct way to do it?
            fprintf(outfile, "%s", inputline[j]);
        }
    }
}

//Function call
    ...
    char inputline[40] = "hello world 123 456"; //passed to the function above
    test(inputline);

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Ошибка в вашем коде, вызывающая ошибку сегментации, заключается в том, что вы передаете char значение inputline[j] в printf для аргумента %s, который ожидает строковый указатель. Это имеет неопределенное поведение.

Чтобы записать не более первых 20 символов строки, вы можете использовать %.20s в качестве спецификатора формата. Также не забудьте закрыть файл:

void test(const char *inputline) {
    FILE *outfile = fopen("results.txt", "w");   
    if (outfile == NULL) {
        perror("Error while opening file: ");
    } else {
        // print at most 20 bytes from inputline
        fprintf(outfile, "%.20s\n", inputline);
        fclose(outfile);
    }
}

Обратите внимание, что при необходимости это максимальное количество может быть переменной с форматом %.*s:

        int limit = 20;
        fprintf(outfile, "%.*s\n", limit, inputline);
2 голосов
/ 27 мая 2020

Спецификатор формата %s в

fprintf(outfile, "%s", inputline[j]);

ожидает переменную char *, но вы фактически передаете char (j th элемент массива inputline) .

Причина, по которой возникает ошибка сегментации, состоит в том, что fprintf пытается «получить доступ» к ячейке памяти, указанной переданным символом. И поскольку это, скорее всего, будет недопустимый адрес , ОС будет жаловаться на попытку доступа к памяти за пределами пространства , назначенного вашему приложению.

Вы можете либо напечатайте в файл char с помощью char , сохраняя for-l oop и используя %c формат

 for(int j=0; j<20; ++j)
 {
     fprintf(outfile, "%c", inputline[j]);
 }

, или распечатайте всю строку, сохраняя формат %s, передавая весь массив и избавившись от for-l oop:

fprintf(outfile, "%s", inputline);

Примечание: в первом случае все равно будет записано 20 символов. Во втором случае «длина + 1» символов из-за терминатора строки '\0'.

...