Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [С/С++] работа с файлами, плохи дела с этой задачкой( 
:(
    Опции темы
elllektra
Дата 17.5.2007, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 14.5.2007

Репутация: 1
Всего: 1



для контрольной не могу решить последние 3 задачки.
Сдать нужно послезавтра, тему с файлами плоховато понимаю(

В файле f записаны числа. Получить в файле g  положительные числа в файле и сумму отрицательных чисел файла f
PM MAIL   Вверх
Anikmar
Дата 17.5.2007, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Можно так:
Код

#include <stdio.h>

int main(int argc, char* argv[])
{
    FILE *InputFile,*OutputFile;
    int Num,SumOtr=0;

    InputFile = fopen("input.txt","r");
    if (InputFile != NULL)
    {
        OutputFile = fopen("out.txt","w+");
        if (OutputFile != NULL)
        {
            while(!feof(InputFile))
            {
                fscanf(InputFile,"%d",&Num);
                if (Num >= 0) fprintf(OutputFile,"%d\n",Num);
                else SumOtr += Num;
            }
            fprintf(OutputFile,"Sum = %d\n",SumOtr);
            fclose(OutputFile);
        }
        fclose(InputFile);
    }
    return 0;
}

PM MAIL ICQ   Вверх
Xenon
Дата 17.5.2007, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



Можно вот так более  С++`сно smile
Код

#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char* argv[])
{
    std::string path_f;
    std::string path_g;
    std::cout << "Enter path to file f: ";
    std::getline(std::cin, path_f);
    std::ifstream file_f( path_f.c_str() );
    if ( !file_f.is_open() )
    {
        std::cout << "File does not exist";
        std::cin.get();
    }
    std::cout << "Enter path to file g: ";    
    std::getline(std::cin, path_g);    
    std::ofstream file_g( path_g.c_str() );
    if ( !file_f.is_open() )
    {
        std::cout << "Could Not create file";
        std::cin.get();
    }
    int sum = 0;
    while (true)
    {
        int num = 0;
        file_f >> num;
        if (num >= 0) file_g << num << ' ';
        else sum += num;
        if ( file_f.eof() ) break;
    }
    file_g << sum;
    std::cin.sync();
    std::cin.get();
    return 0;
}



Это сообщение отредактировал(а) Xenon - 17.5.2007, 19:43


--------------------
user posted image  
PM MAIL   Вверх
Anikmar
Дата 17.5.2007, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Xenon,  у вас нет проверки, что входной файл изначально пуст:
Код

...
    while (true)
    {
        int num = 0;
        file_f >> num;
        if (num >= 0) file_g << num << ' ';
        else sum += num;
        if ( file_f.eof() ) break;
    }
...


И что будет в итоге происходить при ошибках открытия файлов? По идее надо закончить программу при этом. 
PM MAIL ICQ   Вверх
Xenon
Дата 17.5.2007, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



Anikmar, это чертовы глюки ... забыл return вставить smile
Код

#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char* argv[])
{
    std::string path_f;
    std::string path_g;
    std::cout << "Enter path to file f: ";
    std::getline(std::cin, path_f);
    std::ifstream file_f( path_f.c_str() );
    if ( !file_f.is_open() )
    {
        std::cout << "File does not exist";
        std::cin.get();
        return -1;
    }
    std::cout << "Enter path to file g: ";    
    std::getline(std::cin, path_g);    
    std::ofstream file_g( path_g.c_str() );
    if ( !file_f.is_open() )
    {
        std::cout << "Could Not create file";
        std::cin.get();
        return -1;
    }
    int sum = 0;
    while (true)
    {
        int num = 0;
        file_f >> num;
        if (num >= 0) file_g << num << ' ';
        else sum += num;
        if ( file_f.eof() ) break;
    }
    file_g << sum;
    std::cin.sync();
    std::cin.get();
    return 0;
}


А вот со вторым замечанием - а что ты предлагаешь? Проверять на то, что там '\n' и все? или '\0'? И у тебя это разве учитывается? И зачем это нужно? smile Ну если там ничего нет, то сумма равно 0, а значений положительных нет, поэтому пишем в файл 0 ... По-моему логично.

Это сообщение отредактировал(а) Xenon - 18.5.2007, 23:37


--------------------
user posted image  
PM MAIL   Вверх
Anikmar
Дата 17.5.2007, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(Xenon @  17.5.2007,  21:27 Найти цитируемый пост)
А вот со вторым замечанием - а что ты предлагаешь? Проверять на то, что там '\n' и все? или '\0'? И у тебя это разве учитывается? И зачем это нужно?  Ну если там ничего нет, то сумма равно 0, а значений положительных нет, поэтому пишем в файл 0 ... По-моему логично.

В общем то у меня только защита от нулевой длины собственно. Так что наверное вы правы - надо оставить как есть.

PM MAIL ICQ   Вверх
GIK
Дата 18.5.2007, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Добрый человек
**


Профиль
Группа: Участник
Сообщений: 985
Регистрация: 3.6.2005
Где: я только не небыв ал

Репутация: 4
Всего: 14



Anikmar, 
Xenon, 
Я дико извиняюсь, и нехочу быть невежой, но я несмог с помощью Ваших примеров осуществить задачу... 
Вот кое-что набросал, работает корректно, если определть зазделители между числами символом "," и конец файла символом "."
Так примерно должен выглядеть файл:
-12,45,45,-4,-1234,-233. 
Код:
Код

#include<cstdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<iostream.h>
#include<fstream.h>
#include<math.h>

struct itog{
  int it[256];
}itog_={0}; //

int main(int argc, char* argv[])
{
  char ch='1', path[21]={0};
  int i=0, j=0, y=0, e=0;
  int ran=0, n=0;
  int ran2[5]={0}; //Íå áîëåå 5-çíà÷íîãî ÷èñëà
  bool minus=false;

  std::cout<<"Vvedite adres faila ishodnih dannih:\n";
  std::cin>>path;

  fstream from(path, std::ios::in | std::ios::binary);
  if(!from){printf("%s", "Not File"); getch(); return 1;};

   ch=from.get();
   i=ch;
   std::cout<<i<<"--";

 while(true) //Íå äîâåðÿþ ÿ eof ;)
 {    //Ñ÷èòûâàåì äî çàïÿòîé
      for(i=0; ch!=44 && ch!=46 ;i++)   //Ïîêà íå äîéäåì äî ',' èëè òî÷êè (êîíåö ôàéëà)
      {
       ch=from.get();
       if(ch!=44 && ch!=46)
       {if(ch==45) {minus=true; continue;} //ýòî ÷èñëî ÿâíî çàäóìàííî îòðèöàòåëüíûì :)
        ran=ch-48;
        ran2[i]=ran; //Ñîáèðàåì i çíà÷íîå ÷èñëî
       }
      }

      i--; //Íàäî óìåíüøèòü íà 1

      ran=0;
      e=i;
      //Ñîáèðàåì ÷èñëî
      for(y=0; i!=0; i--, y++)
      {
       if(i-1!=0)
       ran+=ran2[y]*pow(10, (i-1)); //Ïðè÷åì ïîñëåäíåå ÷èñëî êîãäà i=0 ïðè âîçâåäåíèè äîëæíî âîçâðàòèòü 1 à íå 0
       else ran+=ran2[y];
      }
      if(minus) ran*=-1;

       for(i=0; i<e; i++) //×èñòèì ìàññèâ
        ran2[i]=0;

      itog_.it[j]=ran;
      j++;
      if(ch==46) break; //Îñòàíîâèòñÿ ìîæíî íà ëþáîì ÷èñëå, ýòî Âàø âûáîð :)
      ch='1'; minus=false;
  }


    std::cout<<"Fail f soderjit chisla:\n";
    for(i=0; i<j; i++)
     std::cout<<itog_.it[i]<<",";

    //À òåïåðü çàíåñåì íàø ðåçóëüòàò

    from.clear();
    from.close();

    std::cout<<"Vvedite adres faila kuda zapisat itogi:\n";
    std::cin>>path;
   ran=1;
   fstream out(path, std::ios::out | std::ios::binary);
   if(!out){printf("%s", "Not File"); getch(); return 1;};

   //Âñå ïîëîæèòåëüíûå ÷èñëà
   for(i=0; i<j; i++)
     if(itog_.it[i] >= 0)
    out<<itog_.it[i]<<",";

    for(i=0; i<j; i++)
     if(itog_.it[i] < 0){ ran+=itog_.it[i];}
    out<<ran;


  out.close();
  getch();
        return 0;
}


Добавлено через 7 минут и 13 секунд
Вариант с выбором разделителя и конца файла:
Код

#include<cstdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<iostream.h>
#include<fstream.h>
#include<math.h>

struct itog{
  int it[256];
}itog_={0}; //

int main(int argc, char* argv[])
{
  char ch='1', path[21]={0};
  int i=0, j=0, y=0, e=0;
  int ran=0, n=0;
  int ran2[5]={0}; //Íå áîëåå 5-çíà÷íîãî ÷èñëà
  bool minus=false;
  char razd=',';
  char eof='.';


  std::cout<<"Vvedite adres faila ishodnih dannih:\n";
  std::cin>>path;

  std::cout<<"Vvedite razdeliteli:\n";
  std::cin>>razd;
  std::cout<<"Vvedite konec faila:\n";
  std::cin>>eof;



  fstream from(path, std::ios::in | std::ios::binary);
  if(!from){printf("%s", "Not File"); getch(); return 1;};

   ch=from.get();
   i=ch;
   std::cout<<i<<"--";

 while(true) //Íå äîâåðÿþ ÿ eof ;)
 {    //Ñ÷èòûâàåì äî çàïÿòîé
      for(i=0; ch!=razd && ch!=eof ;i++)   //Ïîêà íå äîéäåì äî ',' èëè òî÷êè (êîíåö ôàéëà)
      {
       ch=from.get();
       if(ch!=razd && ch!=eof)
       {if(ch==45) {minus=true; continue;} //ýòî ÷èñëî ÿâíî çàäóìàííî îòðèöàòåëüíûì :)
        ran=ch-48;
        ran2[i]=ran; //Ñîáèðàåì i çíà÷íîå ÷èñëî
       }
      }

      i--; //Íàäî óìåíüøèòü íà 1

      ran=0;
      e=i;
      //Ñîáèðàåì ÷èñëî
      for(y=0; i!=0; i--, y++)
      {
       if(i-1!=0)
       ran+=ran2[y]*pow(10, (i-1)); //Ïðè÷åì ïîñëåäíåå ÷èñëî êîãäà i=0 ïðè âîçâåäåíèè äîëæíî âîçâðàòèòü 1 à íå 0
       else ran+=ran2[y];
      }
      if(minus) ran*=-1;

       for(i=0; i<e; i++) //×èñòèì ìàññèâ
        ran2[i]=0;

      itog_.it[j]=ran;
      j++;
      if(ch==eof) break; //Îñòàíîâèòñÿ ìîæíî íà ëþáîì ÷èñëå, ýòî Âàø âûáîð :)
      ch='1'; minus=false;
  }


    std::cout<<"Fail f soderjit chisla:\n";
    for(i=0; i<j; i++)
     std::cout<<itog_.it[i]<<",";

    //À òåïåðü çàíåñåì íàø ðåçóëüòàò

    from.clear();
    from.close();

    std::cout<<"Vvedite adres faila kuda zapisat itogi:\n";
    std::cin>>path;
   ran=1;
   fstream out(path, std::ios::out | std::ios::binary);
   if(!out){printf("%s", "Not File"); getch(); return 1;};

   //Âñå ïîëîæèòåëüíûå ÷èñëà
   for(i=0; i<j; i++)
     if(itog_.it[i] >= 0)
    out<<itog_.it[i]<<",";

    for(i=0; i<j; i++)
     if(itog_.it[i] < 0){ ran+=itog_.it[i];}
    out<<ran;


  out.close();
  getch();
        return 0;
}



--------------------
Математика=>пиво=> програмирование, три вещи последовательны и совместимы !!!
Программирование - это не деятельнось! Программирование - это состояние души!
Бог - самый крутой программист.
PM MAIL ICQ   Вверх
Anikmar
Дата 18.5.2007, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(GIK @  18.5.2007,  22:43 Найти цитируемый пост)
Anikmar, 
Xenon, 
Я дико извиняюсь, и нехочу быть невежой, но я несмог с помощью Ваших примеров осуществить задачу... 

Перед тем как выложить на форум, я свой код проверил. Работает.

Так что я не понимаю, почему вы не смогли осуществить задачу...
PM MAIL ICQ   Вверх
Xenon
Дата 18.5.2007, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



Мой код тоже работает. Не очень понимаю в чем, собственно, неосуществление smile

Добавлено через 1 минуту и 54 секунды
Но у тебя алгоритм какой-то адский ... если я привел почти С++ вариант, а Anikmar чисто C, то у тебя чего-то ... непонятное smile Если бы комментарии были бы в той кодировке, что надо, возможно и можно было с первого взгляда понять как это работает, но сейчас ...


--------------------
user posted image  
PM MAIL   Вверх
GIK
Дата 19.5.2007, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Добрый человек
**


Профиль
Группа: Участник
Сообщений: 985
Регистрация: 3.6.2005
Где: я только не небыв ал

Репутация: 4
Всего: 14



Согласен, код зверский, писал с бодуна smile
Код

while(true) //не доверяю я eof :)
 {  
   Сначало вытаскиваем символ, визуально похожий на число :) 
      вычитаем 48 и получаем целочислительный эквивалент 
      Разделителем будем считать запятую, ее целочислительный эквивалент = 44, и 
     учтем конец файла, пусть будет символ "." = 46
     Будем учитывать отрицательные числа, если найдем минус, эквивалент = 45, то
    не включим его в собираемое по частям число (в массив ran2[])
    Переменная i предусмотрена для возведения в степень числа 10. 
    Пример:
    число 123, посимвольно собираем в массив, чтобы получить полное число.
    Имеем трех значное число, значит начинаем возводить со степени 2, или i-1=2, получаем 100, 
    Умножаем 100 на 1 и присваиваем переменной ran. далее возводим 10 в степень 1 получаем 10 и умножаем на следующее число, 2 получаем 20, в итоге уже есть 120. Далее нюанс, возводить в 0, не есть хорошо, поэтоме проверяем и просто приплюсуем число 3
 Вот это самое сложно в коде, но если один раз вкурить, то потом не задумываешся о сложности кода, и все дается лекго.

  */
    //Собираем число в массив
      for(i=0; ch!=44 && ch!=46 ;i++)   
      {
       ch=from.get();
       if(ch!=44 && ch!=46)
       {if(ch==45) {minus=true; continue;} //Учтем минус
        ran=ch-48; //Готовое число
        ran2[i]=ran; //
       }
      }

      i--; //нужно уменьшить

      ran=0;
      e=i; //передадим кол-во чисел, i используем для возведения в степень.
     //собираем число из частей 
      for(y=0; i!=0; i--, y++)
      {
       if(i-1!=0)
       ran+=ran2[y]*pow(10, (i-1)); //
       else ran+=ran2[y];
      }
      if(minus) ran*=-1; //Если число отрицательное, то сделаем его отрицательным

       for(i=0; i<e; i++) //Обнуляем массив
        ran2[i]=0;

      itog_.it[j]=ran; 
      j++;
      if(ch==46) break; //вот и дошли до конца файла :), и некакой eof не нужен
      ch='1'; minus=false;
  }



--------------------
Математика=>пиво=> програмирование, три вещи последовательны и совместимы !!!
Программирование - это не деятельнось! Программирование - это состояние души!
Бог - самый крутой программист.
PM MAIL ICQ   Вверх
Xenon
Дата 19.5.2007, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



GIK, Господи ... а прочитать до ',' в некий массив символов и воспользоваться atoi нельзя что ли? smile
А чем тебе eof не нравится? 46 строчку на if( file.eof() ) break; и все окей будет smile
Ну если идти по принципу велосипедов, я бы конвертировал так
Код

int my_atoi(const std::string& arr)
{
    int sign = 1;
    int beg = 0;
    if (arr[0] == '-')
    {
        sign = -1;
        beg = 1;
    }
    int var = 0;
    for (int i = arr.size() - 1, degree = 1; i >= beg; --i, degree *=10 ) var += (arr[i] - '0') * degree;
    return var * sign;
}
    
int main(int argc, char* argv[])
{
    std::string buf;
    std::ifstream file("...");
    while (true)
    {
        std::getline(file, buf, ',');    
        if ( file.eof() ) break;
        std::cout << my_atoi(buf);
    }
    return 0;
}

PS. Не нравится string - спокойно на char* поменять можно и size() на std::strlen()

Это сообщение отредактировал(а) Xenon - 19.5.2007, 14:12


--------------------
user posted image  
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0579 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.