Функция open() не распознается

Мой код включает операции с файлами с использованием open() и связанных с ним функций. Но я сталкиваюсь с ошибкой «идентификатор не найден» для open(), хотя я включил необходимый заголовок (<fcntl.h>).

#include <fcntl.h>
#include <unistd.h>
#include <iostream>

int main() {
    // Relevant code using open() function
    int fd = open("file.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // Further operations involving file descriptors

    close(fd); // Closing the file descriptor
    return 0;
}

Насколько я понимаю, open() — это стандартная функция для файловых операций в UNIX-подобных системах, но, похоже, компилятор не может ее найти. Не могли бы вы помочь объяснить, почему может возникнуть эта ошибка и как ее устранить?

Мне кажется в io.h, и надо сказать #pragma warning(disable : 4996). («Это имя устарело, поскольку оно не соответствует правилам стандарта C для имен, специфичных для реализации».)

Peter - Reinstate Monica 19.06.2024 18:45

См. Learn.microsoft.com/en-us/cpp/c-runtime-library/reference/… вы не используете UNIX-подобную систему, вы используете Windows, поэтому вам нужно просмотреть документацию Microsoft.

Alan Birtles 19.06.2024 18:47

@AlanBirtles Я просмотрел эту страницу и не увидел требования io.h. (Хотя иногда я слеп.)

Peter - Reinstate Monica 19.06.2024 18:49

@Peter-ReinstateMonica см. «Требования» внизу (довольно стандартно для документов Microsoft)

Alan Birtles 19.06.2024 18:50

@AlanBirtles Ах, заголовки внизу. Имеет полный смысл, тем более, как правило ;-).

Peter - Reinstate Monica 19.06.2024 18:56

Спасибо, я последовал совету и включил предупреждение #pragma(disable: 4996), как было предложено, и это решило проблему с устаревшими функциями в <io.h>. Это помогло мне успешно скомпилировать и запустить код без появления предупреждений. Я благодарен за помощь!

user25479256 19.06.2024 18:59

Есть ли причина, по которой вы не используете производную ifstream? Смотрите std::ifstream::open().

Thomas Matthews 19.06.2024 19:03

Если вам необходимо использовать функции, не относящиеся к стандартному языку C++, вам следует проверить MSDN: Создание и открытие файлов

Thomas Matthews 19.06.2024 19:05
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Windows и Visual C++ имеют собственную версию открытия/закрытия, требующую ведущего подчеркивания.

#define _CRT_SECURE_NO_WARNINGS

#include <io.h>
#include <fcntl.h>
#include <iostream>

int main() {
    // Relevant code using open() function
    int fd = _open("file.txt", _O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    // Further operations involving file descriptors

    _close(fd); // Closing the file descriptor
    return 0;
}

Или даже лучше. Отбросьте определение _CRT_SECURE_NO_WARNINGS и используйте его, чтобы открыть файл:

auto err = _sopen_s(&fd, "d:/save2.txt", _O_RDONLY, _SH_DENYWR, 0);
if (err != 0) {
    perror("open");
    return 1;
}
Ответ принят как подходящий

Несмотря на то, что это одна из самых основных и распространенных функций C, open() «зависит от реализации»: это POSIX функция. Теперь POSIX — это попытка быть «переносимым», но в основном между различными вариантами Unix. Не каждая операционная система, программируемая на C, имеет собственные целочисленные «дескрипторы файлов»; это концепция *nix.

Другие операционные системы, включая ранние версии Windows NT (и, как мы видим, современную Windows), иногда обеспечивают ту или иную степень поддержки функций POSIX. Причина, несомненно, в том, чтобы помочь перенести с *nix-систем на эти целевые системы хотя бы такие программы, которые используют только базовые, простые в реализации функциональные возможности POSIX.

По-настоящему переносимый способ выполнения ввода-вывода — через стандартную библиотеку C (и, кроме того, для программ C++) (fopen(), ifstream()). Структура FILE, с которой работает стандартная библиотека C, «непрозрачна»: функции возвращают и получают указатели (или, в C++, ссылки), так что пользователь может игнорировать их внутреннюю структуру.

Почему же Microsoft объявляет устаревшим open() и заменяет его на _open()?

Стандарт C++ требует в 5.10 «Идентификаторы»:

Каждый идентификатор, начинающийся с подчеркивания, зарезервирован для реализации и может использоваться в качестве имени в глобальном пространстве имен.

Я не воспринимаю это как создание определяемых реализацией идентификаторов, которые не начинаются с подчеркивания, несовместимого; но пользователи могут справедливо удивиться столкновениям таких имен с именами, введенными реализацией. Следовательно, Microsoft изменила имя на _open(), имя, которое зарезервировано для реализаций. Старое имя вызывает предупреждение C4996, которое, похоже, превратилось в ошибку — чтобы этого избежать, нужно добавить #pragma warning(disable : 4996).

Наконец, документация для _open() содержит, как правильно заметил Алан Бертлз, необходимый заголовок io.h в разделе Требования.

Другие вопросы по теме