Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Файловый I/O


Автор: OXOTHUK 29.12.2005, 15:39
Люди у меня через неделю городская олимпиада. Раньше я писал на Паскале, но перешёл на C++. Там требуют читать из файла данные и записывать ответ. Я на си могу только записывать и только через fstream. Читать не получается. Например надо прочитать:

2 3
5
АБВ

Числа 2, 3, 5 записать в 3 int`а, а строку в char*.
Я что-то выдел, что можно через FILE, но не знаю как работает.
В паскале там всё просто с этим, мне надо так, чтобы не писать огромных функций по чтению. Help, plz.

Автор: Exekutor 29.12.2005, 15:42
функции scanf и др. тебе в помощь

Автор: Void 29.12.2005, 15:52
Ну fstream, так fstream:
Код

std::ifstream input("file.txt");
int a, b, c;
const size_t bufsize = 128;
char buf[bufsize]; // Я бы все-таки взял std::string
input >> a >> b >> c;
input.getline(buf, bufsize); // считает в buf не более bufsize - 1 символов, до конца строки

Автор: TheBoss 29.12.2005, 16:08
Код

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
   FILE *stdin;
   int i;

   printf("Input an integer: ");

   /* read an integer from the
      standard input stream */
   if (fscanf(stdin, "%d", &i))
      printf("The integer read was: %i\n", i);
   else
   {
      fprintf(stderr, "Error reading an integer from stdin.\n");
      exit(1);
   }
   return 0;
}

Автор: OXOTHUK 30.12.2005, 15:43
TheBoss
Что-то не совсем понял код. Объявить - объявил файл, но ни адреса, ни открытия.
Void
Ну ввёл я в прогу:
Код

#include <fstream.h>
#include <conio.h>
#include <iostream.h>

int main()
{
    clrscr();
    ifstream fin("D:\1.txt");
    int a=0, b=0, c=0;
    char str[256];
    fin>>a>>b>>c;
    fin.getline(str, 256);
    fin.close();
    cout<<a<<" "<<b<<'\n'<<c<<'\n'<<str;

    getch();
    return 0;
}

Создал файл на диске D: под именем 1.txt, ввёл туда:
2 3
5
ABC
Запустил прогу и смотрю результат:
0 0
0

Т. е. 3 нуля и пустая строка, т. е. ничего не прочиталось. Именно из-за этого и у меня не получалось.
А строки не согу, т. к. у меня Turbo C++ 3.0 и там видимо устаревший стандарт С\С++:
там нету bool и true/false(вместо них int и 1/0). Также я не нашёл string`а.

Автор: dronzo 30.12.2005, 16:59
OXOTHUK

Код

// ifstream fin("D:\1.txt"); 
ifstream fin ("D:\\1.txt");

//fin.getline(str,256)
fin >> str;


Dev-C++ по крайней мере съел.

Автор: Void 30.12.2005, 17:59
OXOTHUK
У тебя просто файл не открылся. Бэкслэш надо писать двойной.

Цитата(dronzo @ 30.12.2005, 18:59)
fin >> str;

Рискуем нарваться на buffer overrun. Лучше пользоваться istream::getline, раз уж у нас нет std::string.

Автор: blackofe 30.12.2005, 21:59
Цитата(OXOTHUK @ 30.12.2005, 15:43)
А строки не согу, т. к. у меня Turbo C++ 3.0 и там видимо устаревший стандарт С\С++:
там нету bool и true/false(вместо них int и 1/0). Также я не нашёл string`а.

поправьте меня, если я не прав. но, имхо, bool есть в с++ с самой первой редакции (у меня нет страуструпа первой редакции, но во второй bool точно есть). а вот string, да, появился только в третьей редакции. поскольку во второй редакции страуструп ввел шаблоны, а степанов этим воспользовался, создав STL.

Автор: LPBOY 30.12.2005, 22:26
Цитата(blackofe @ 30.12.2005, 21:59)
поправьте меня, если я не прав. но, имхо, bool есть в с++ с самой первой редакции


Не читал первую редакцию, но вот что дал поиск:
http://www.intuit.ru/department/se/pbmsu/8/3.html
Цитата

...
Язык C++ вводит логический тип bool в явном виде (отметим, что этот тип появился в C++ далеко не сразу!).
...


В BC++3.0 можно сделать так:
Код

typedef enum {false, true} bool;

Все же, чем int и 0/1, несколько лучше имхо.

Автор: OXOTHUK 1.1.2006, 08:57
Void
Цитата
Бэкслэш надо писать двойной


Это как?

P.S. ничего не знаю, но bool мне надо вручную вводить и его готового там нет.

Автор: LPBOY 1.1.2006, 10:57
Цитата(OXOTHUK @ 1.1.2006, 08:57)
Это как?

Очень просто: D:\\1.txt

Автор: nikitao 1.1.2006, 23:22
OXOTHUK
Бэкслэш надо писать двойной потому что компилятор думает что следующий за ним символ вместе с ним образуют специальный символ(к примеру '\n')Представь такое имя файла
Цитата

C:\notepad.exe

Такое имя привело бы к неверной работе.
Но в С++ '\\'=='\' в обычной жизни (это тоже специальная комбинация. smile

Автор: OXOTHUK 2.1.2006, 15:02
Извиняюсь, совсем забыл. Не привык я так писать (долбанный паскаль).

Заработало(прочитал), но строку всё равно не хочет - пустая выводится.

Автор: dronzo 2.1.2006, 15:49
OXOTHUK, Правильно я же тебе сказал - замени fin.getline() на fin >> (про overrun читал smile ). И лучше не мешай их в одном коде. Тут дело в том, что fin>> "\n" не читает, а getline() читает и видит тот самый, непрочитанный "\n", и дальше не суётся. Можно ещё вспомогательную переменную ввести и getline-ом() читать этот одинокий "\n", но это уже извращение будет, ИМХО.

Автор: nikitao 2.1.2006, 16:48
dronzo,твое предложение не есть good еще по одной причине(помимо той что сказаал Void):
Возьмем такой файл:
239
30
566
Hello world

Очевидно,что нам нужно,чтобы в строке оказалось Hello world,а разумеется окажется Hello .Это проблему ессно решает getline.


OXOTHUK
Если не понял обьяню более наглядно.На самом деле файл который я написал выше представляет вид ,что-то типа этого:
239\n
30\n
566\n
Hello world

Оператор >> по умолчанию пропускает все знаки разделители ,затем записывает в указаную переменную данный до следующего знака разделителя или до "знака другого типа"(к примеру если строка 12345Vingrad ,то после fin>>a,окажется в a 12345).
Получается что после строки в коде
Код

fin>>a>>b>>c;

Файловый указатель указывает на последний '\n'
В свою очередь getline работает по другому:Она ничего не пропускает,но символы типа '\n' являются для нее указанием ,что это конец строки.Таковым оказывается 1 считаный ей символ=>str остается пустым.В результате всего надо просто ввести "темповый" символ.
Код

#include <fstream>
#include <conio.h>
#include <iostream>
char str[256];
using namespace std;
int main()
{
    char ch;
    ifstream fin("D:\\1.txt");
    int a=0, b=0, c=0;
    fin>>a>>b>>c;
    fin.getline(&ch,1);
    fin.getline(str,256);
    fin.close();
    cout<<a<<'\n'<<b<<'\n'<<c<<'\n'<<str;
    getch();
    return 0;
}

Автор: dronzo 2.1.2006, 17:00
nikitao Да, это я немного на примере застопорился smile Но тогда ведь и в твоём примере в случае наличия больше, чем одной строки "Hellow World", тоже отнюдь не всё будет прочитано smile Моё предложение было в том, чтобы не мешать или один символ getline-ом читатать во вспомогательную переменную, так как ты и привёл ниже в примере, если всё-таки собрались мешать.

Автор: OXOTHUK 3.1.2006, 13:12
Я так поэкспериментировал и понял, что:
1) После чтения чисел fin.getline(str, 256); надо писать 2 раза(не занимать память всякими темповыми, а просто 2 раза).
2) После чтения строки можно(и нужно) и один раз.

А вот дана строка и надо почитать слова в разные строки.
Это значит надо:
Код

char *str1, *str2, *str3;
fin>>str1>>str2>>str3;


Например:
есть файл 1.txt:
ABC DEF GHI

Прога:
Код

#include <fstream.h>
#include <conio.h>
#include <iostream.h>

int main()
{
    clrscr();
    ifstream fin("D:\\1.txt");
    char *str1, *str2, *str3;
    fin>>str1;
    cout<<str1;
    fin>>str2;
    cout<<str2;
    fin>>str3;
    cout<<str3;
    fin.close();
    getch();
    return 0;
}


Получается - он прочитал: ABCDEF (а где GHI?)

Я следал:
Код

...
    fin>>str1;
    cout<<str1;
    fin>>str2;
    cout<<str2;
    fin>>str3;
    cout<<str3;
    fin>>str3;
    cout<<str3;
...


Тогда он всё напечатал: ABCDEFGHI
Почему он не прочитал третье слово?

Автор: Void 3.1.2006, 13:18
Цитата(OXOTHUK @ 3.1.2006, 15:12)
    char *str1, *str2, *str3;
    fin>>str1;
    cout<<str1;
    fin>>str2;
    cout<<str2;
    fin>>str3;
    cout<<str3;

Куда по-твоему читатются строки из файла? Под str1, str2, str3 не выделена память и они указывают неизвестно куда.
Если же это просто опечатка, и память ты на самом деле выделял - что ж, есть единственный способ избавиться от этих проблем: выбросить Turbo C++ в топку, и взять нормальный компилятор.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)