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


Автор: Uter123 2.11.2015, 20:58
Написать программу которая считывает текстовый файл , и вывести на экран только цитаты, то есть предложения, помещенные в ковычки.
Проверьте не пойму почему зацикливается.

Код

#include "stdafx.h"
#include "stdio.h"
#include "iostream"
#include "conio.h"
using namespace std;


int main(int argc, char* argv[])
{
    FILE *retro,*etr;
    int i=0,j=0,a,b;
    char x[80]=" ";
    retro=fopen(argv[1],"r+");
    if(retro==NULL)
    {
        cout<<"net faila"<<endl;
        exit(0);
    }
    cout<<"idet zapis v fail...";
    while(!feof(retro))
    {
        fgets( x, 80 , retro ); 
        for(int j=0;x[i]!='\0';j++)
        {
            cout<<endl;
            a=0;b=0;
            for(int i=j;x[i]!='\0';i++)
            {
                if(x[i]=='"')
                {
                    a=i;
                    break;
                }
            }
            for(int i=a+1;x[i]!='\0';i++)
            {
                if(x[i]=='"')
                {
                    b=i;
                    break;
                }
            }
            for(int i=a;i<=b;i++)
            {
                cout<<x[i];
            }
            j=b+2;
        }
    }
    fclose(retro);
    _getch();
    return 0;
}

Автор: feodorv 2.11.2015, 21:37
Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
Проверьте не пойму почему зацикливается.
Весь код не смотрел. Но сходу заметно такое:
Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
       for(int j=0;x[ ij ]!='\0';j++)



Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
            j=b+2;
Почему +2???


Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
    while(!feof(retro))
    {
        fgets( x, 80 , retro ); 
Корректно это записывается так:
Код

while( fgets( x, 80 , retro ) != NULL )


Автор: rudolfninja 2.11.2015, 21:39
Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
for(int j=0;x[i]!='\0';j++)

Подозреваю, что у вас x[i] никогда не будет равно нулевому символу, потому что в i у вас храниться индекс ковычек.
Во-вторых, у вас может быть выход за пределы массива в случае, когда строка заканчивается ковычкой. 
Код

j=b+2;

Вот именно из-за этого и получится так.

Предлагаю вам такой вариант:

Код

for (int j = 0; x[j] != '\0', j <= strlen(x); j++)
    {
        a = 0; b = 0;
        for (int i = j; x[i] != '\0'; i++)
        {
            if (x[i] == '"')
            {
                a = i;
                break;
            }
        }
        for (int i = a + 1; x[i] != '\0'; i++)
        {
            if (x[i] == '"')
            {
                b = i;
                break;
            }
        }
        for (int i = a; i <= b; i++)
        {
            cout << x[i];
        }
        j = b + 1;
    }

Автор: Uter123 2.11.2015, 21:41
 там j=b+1; это попытка исправить зацикливание.

Автор: feodorv 2.11.2015, 21:51
Цитата(Uter123 @  2.11.2015,  21:41 Найти цитируемый пост)
там j=b+1; это попытка исправить зацикливание. 

Тоже не верно. Зачем +1???


Как насчет 
Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
for(int j=0;x[i]!='\0';j++)
???

Автор: rudolfninja 2.11.2015, 21:53
Цитата(feodorv @  2.11.2015,  21:51 Найти цитируемый пост)
Тоже не верно. Зачем +1???

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

Автор: feodorv 2.11.2015, 21:56
Цитата(rudolfninja @  2.11.2015,  21:53 Найти цитируемый пост)
Как я понимаю, чтоб избежать ненужные итерации. В b хранится индекс ковычек, поэтому есть смысл двигаться от них, а не от следующего символа 

"+1" это не оправдывает)))

Автор: Uter123 2.11.2015, 22:00
Это чтобы когда нашли одно вхождение ковычек, можно было двигаться дальше чтобы найти следующее  вхождение ковычек.

Автор: feodorv 2.11.2015, 22:11
Цитата(Uter123 @  2.11.2015,  22:00 Найти цитируемый пост)
Это чтобы когда нашли одно вхождение ковычек, можно было двигаться дальше чтобы найти следующее  вхождение ковычек.

Это понятно. Но зачем здесь лишнее "+1"? Если бы Вы оформили код так:
Код

int j = 0;
while( x[j] != '\0' )
{
   ...
   j = b+1;
}
то вопросов бы не возникло. Но ведь у Вас полноценный for:
Цитата(Uter123 @  2.11.2015,  20:58 Найти цитируемый пост)
        for(int j=0;x[j]!='\0';j++)


Автор: math64 3.11.2015, 08:40
Цитата(rudolfninja @  2.11.2015,  21:39 Найти цитируемый пост)
Код
for (int j = 0; x[j] != '\0', j <= strlen(x); j++)

Результат [j] != '\0' будет игнорироваться.
Нужно x[j] != '\0' && j <= strlen(x) - хотя вторая проверка лишняя.

Автор: xvr 3.11.2015, 14:26
Как то у вас всё сложно и запутанно. Задача решается гораздо проще (привожу только внутренний цикл и оставляю помесь ostream/FILE как у вас было):
Код

FILE* retro;
bool in_quote = false;
int sym;
...

while( (sym=fgetc(retro)) != EOF)
{
  if (sym=='"')
   {
     in_quote=!in_quote;
     if (!in_quote) cout << endl;
   }
  else if (in_quote) cout << (char)sym;
}


Автор: feodorv 3.11.2015, 14:39
Цитата(xvr @  3.11.2015,  14:26 Найти цитируемый пост)
Задача решается гораздо проще 

Кстати, и правильнее, так как находятся цитаты, расположенные на нескольких строчках.

Автор: Uter123 3.11.2015, 21:03
Нам препод не разрешает использовать   bool. Говорит чтобы мы его обходили стороной.

Автор: feodorv 3.11.2015, 21:27
Цитата(Uter123 @  3.11.2015,  21:03 Найти цитируемый пост)
Говорит чтобы мы его обходили стороной.
Ну так обходите:
Код

FILE* retro;
int in_quote = 0;
int sym;
...
while( (sym=fgetc(retro)) != EOF)
{
  if (sym=='"')
   {
     in_quote=!in_quote;
     if (!in_quote) cout << endl;
   }
  else if (in_quote) cout << (char)sym;
}

Автор: Uter123 4.11.2015, 17:39
А что означает эта строка :
in_quote=!in_quote;

Автор: feodorv 4.11.2015, 20:54
Цитата(Uter123 @  4.11.2015,  17:39 Найти цитируемый пост)
А что означает эта строка :
in_quote=!in_quote; 

Что-то вроде:
Код

if( in_quote ) in_quote = 0; else in_quote = 1;

То есть если значение переменной in_quote ненулевое, то делаем его нулём; если же значение переменной in_quote нулевое, то делаем его ненулевым.

Ненулевое значение переменной in_quote сигнализирует о том, что мы находимся внутри цитаты (и, соответственно, нужен вывод этой цитаты на экран); нулевое значение переменной in_quote говорит о том, что цитата ещё не началась, нужно ждать символа ".

Автор: math64 5.11.2015, 08:51
Цитата(Uter123 @  4.11.2015,  17:39 Найти цитируемый пост)
А что означает эта строка :
in_quote=!in_quote; 

Код

if (in_quote == 0)
  in_quote = 1;
else
  in_quote = 0;

А можно так (у препода не будет повода сказать, что in_qoute - имитация bool):
Код

int quote_count = 0;
int sym;
...
while( (sym=fgetc(retro)) != EOF)
{
  if (sym=='"')
   {
     quote_count++;
     if (quote_count%2 == 0) cout << endl;
   }
  else if (quote_count%2 != 0) cout << (char)sym;
}

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