g Неполный тип для ifstream, присутствуют правильные заголовочные файлы

#c #file-io

#c #file-io

Вопрос:

Доброе утро,

Я пытаюсь прочитать файл, используя C , скомпилированный с помощью g (g (Ubuntu 4.4.3-4ubuntu5) 4.4.3). Tis компилируется и работает под управлением MSVC 2008

Сильно урезанный вот мой код:

    #include <iostream>
   #include <fstream>

   int main(int argc, char* argv[]) 
   {
      const char filename[] ("~/Serial.Number")

      std::ifstream           afile       ( fileName );
       if ( afile.is_open() )
       {
          // read input
          afile.close();
       }
    }
 

Все, что я прочитал, говорит о том, что этого достаточно, чтобы заставить входной файл работать. Когда я пишу это (повторные попытки), курсор Eclipse над «компилятором» сообщает, что «afile» является ifstream. Тем не менее, после того, как я скомпилирую его, снова наведя курсор на «afile», я получаю «Неполный тип …».

Еще более странно, когда я запускаю программу (режим отладки) Он запускается, никаких ошибок, никаких исключений, но файл никогда не открывается, а .is_open() имеет значение false .

Есть идеи?

Wes

Комментарии:

1. Я подозреваю, что вы не можете использовать «~» в имени. AFAIK, символ «~» расширяется только оболочкой в командной строке.

2. Упс, я неправильно набрал текст. Это действительно был прямой удар. И, да, ~ была моей настоящей проблемой. Никогда не знал, что несуществующий файл будет отображаться как неполный тип. Очень интересно. Спасибо, Уэс

Ответ №1:

Очень вероятно ~Serial.Number , что в вашей системе Linux нет файла с именем. Это не означает, что вы, вероятно, хотите (файл с именем Serial.Number в вашем домашнем каталоге).

Путь к файлу ~Serial.Number в Linux, когда он передается open системному вызову или файловому потоку C , будет означать имя файла, начинающееся с тильды ~ , за которой следует обратная косая черта, существование которой очень маловероятно (даже если это возможно в принципе).

Вероятно, вы хотите получить домашний каталог с помощью getenv("HOME") и присоединить его к "/Serial.Number" строке (начиная с обычной косой черты, а не обратной косой черты).

С уважением.

Ответ №2:

~ И S выглядит подозрительно для меня. Как указал @wilx, это имеет смысл только для оболочки, а не для файловых методов ввода-вывода. Создайте полный путь с $HOME помощью переменной среды пользователя:

 std::string fullpath = getenv("HOME");
fullpath  = "/Serial.Number";
...
 

Ответ №3:

Есть несколько проблем:

  • Если g успешно компилирует код, то он (очевидно) способен разрешить необходимые типы, даже если анализатор C Eclipse по какой-либо причине не может. Заставить Eclipse правильно разрешать типы — это отдельный вопрос.
  • Использование ~ в вашем имени файла, вероятно, не будет делать то, что вы ожидаете. Использование его из оболочки Unix или Linux относится к вашему домашнему каталогу, потому что оболочка расширяет его до вашего домашнего каталога, но использование его из кода приложения относится к буквальному ~ каталогу.
  • Обратная косая черта — это управляющий символ C и C . Так S же, как и специальный символ (точно так n же, как и новая строка). Поскольку S in particular не является одним из escape-символов C и C , я удивлен, что ваш компилятор не жалуется. Вместо этого вам следует экранировать обратную косую черту (т. Е. "~\Serial.number" ) Для Windows, или использовать косую черту ( "~/Serial.number" ) для Linux (которая также будет работать в Windows), или использовать кроссплатформенную библиотеку (например, Boost.Файловая система), которая позаботится о различиях в путях для вас.