Это код c, который я написал для записи чего-либо в файл. Но когда я его компилирую, процесс завершается без ввода содержимого. В чем ошибка?

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

void main()
{
    FILE *fp;
    char name[20];
    char content[100];

    printf("Enter file name:\n");
    scanf("%s", name);

    printf("Enter the content:\n");
    gets(content);

    fp = fopen(name, "w");

    fprintf(fp, "%s", content);
    fclose(fp);
}
c
-3
Basanta Goswami 23 Сен 2018 в 20:33

1 ответ

Лучший ответ

Он пролетел мимо линии gets. Почему? Поскольку у семейства scanf очень много проблем. Избежать их.

В частности, он имеет тенденцию оставлять ввод в буфере. В этом случае scanf("%s", name); прочитал весь текст и оставил новую строку на stdin. Затем gets послушно прочтите этот символ новой строки ... и выбросите его, потому что именно так ведет себя gets. Мы можем увидеть это, если напечатаем имя и контент непосредственно перед gets.

printf("name: '%s'\n", name);
printf("content: '%s'\n", content);

name: 'foo'
content: ''

Тогда ваша программа послушно ничего не записывает в файл.

Вместо этого используйте fgets для чтения целых строк и sscanf для их анализа. Это позволяет избежать опасности оставить ввод в буфере.

printf("Enter file name:\n");
fgets(name, sizeof(name), stdin);

printf("Enter the content:\n");
fgets(content, sizeof(content), stdin);

fgets не удаляет символы новой строки, поэтому вам придется сделать это самостоятельно. Это можно сделать разными способами.

void trim( char *string, char to_trim ) {
    size_t len = strlen(string);
    if( len == 0 ) {
        return;
    }
    size_t last_idx = len -1;
    if( string[last_idx] == to_trim ) {
        string[last_idx] = '\0';
    }
}

Я предпочитаю этот подход, потому что он удаляет новую строку только в том случае, если это последний символ.

Наконец, всегда проверяйте операции с файлами . Вы не проверяете, удалось ли выполнить fopen. Если по какой-либо причине произойдет сбой, вы получите еще одну загадочную ошибку. В моем случае имя, которое я использовал для тестирования, уже существовало как каталог.

#include <string.h>  // for strerror
#include <errno.h>   // for errno

fp = fopen(name, "w");
if( fp == NULL ) {
    fprintf(stderr, "Could not open '%s' for writing: %s.\n", name, strerror(errno));
    return 1;
}
0
Schwern 23 Сен 2018 в 18:18