Форум программистов, компьютерный форум CyberForum.ru

Работа со строками - C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.94
Алексей Студент
Сообщений: n/a
11.12.2008, 17:20     Работа со строками #1
Товарищи, такая вот проблема. Есть задача. Прочитать строки из файла, а потом записать их следующим образом. Первую оставить, вторую -удалить, на месте её - пустая строка. Третью - оставить, на месте следующих двух - две пустые строки. Шестую - оставить, затем три пустые строки.
При этом все, даже пустые, строки должны быть пронумированы.

Сам написал такой вот бред, но думаю можно проще и правильнее.
Код
main()
{
fstream file;
file.open("D:\1.txt",ios::in);
char a[256];
char*s=new char[];
int i=0;
while(!file.eof())
{ 
    file.getline(a,256,"\n");
    for(int j=0; j<(int)(strlen(a));j++)
    {s[i]=a[j];
    i++;}
    s[i]=";";
    i++;
}
file.close();

int z=0;
int d=1;
int f=1;
file.open("D:\1.txt",ios::out);
for(int b=0; b<(int)(strlen(s));b++)
{
    file<<s[b];
    if(s[b]==;)
    {
        for(int c=0; c<d; c++)
        {file<<"\n";}
        for(int e=0; e<f; e++)
        {
        while(s[b+1]!=;)
        {z=b+1;}}
    b=z;d++;f++;}
}
file.close();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.12.2008, 17:20     Работа со строками
Посмотрите здесь:

работа со строками C++
C++ Работа со строками C++
C++ Работа со строками
C++ Работа со строками в СИ++
C++ Работа со строками
Работа со строками C++
C++ Работа со строками
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
11.12.2008, 20:00     Работа со строками #2
Код
 
#include <stdio.h>

#define MAXLINE  1000    /* максимальная длина строки */
#define IN  1            /* внутри пропусков */
#define OUT 0            /* снаружи пропусков */

/* читает строки из файла, а потом записывает их определённым образом 
   первую оставить, вторую - удалить, на месте её - пустая строка и т.д. */
main()
{
    FILE *fp;
    char line[MAXLINE], *p;
    int state;
    long i, j, nl;
        
    if ((fp = fopen("file.txt", "rb")) == NULL)
        return 1;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, fp)) != NULL) {
        nl++;
        if (i == 0) {
            j++;
            i = j;
            state = OUT;
        } else {
            i--;
            state = IN;
        }    
        printf("%03d:%s", nl, (state == OUT ? line : "\n"));
    }
    fclose(fp);
    return 0;
}
Алексей Студент
Сообщений: n/a
12.12.2008, 03:27     Работа со строками #3
Спс. Еще один вопрос - это можно реализовать через класс? (Чтобы файловая переменная принадлежала к классу и была типа Private)
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
12.12.2008, 03:41     Работа со строками #4
есть класс CFile
Алексей Студент
Сообщений: n/a
12.12.2008, 04:55     Работа со строками #5
Про сифайл слышал. Тут дело в другом, надо создать свой собственный класс(пусть будет class1), в котором обьявить файловую переменную(в данном случае это fp) типа private. И чтобы в коде мейна она уже фигурировала как class1.fp. Такое вот задание препод дал.
И еще один вопрос, по коду, который дал accept. Файл он открывает и в консоли записывает все правильно, но вот обратно в файл не записывает. Можете с этим помочь?
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
12.12.2008, 07:58     Работа со строками #6
Код
 
#include <stdio.h>

#define MAXLINE  1000    /* максимальная длина строки */
#define IN  1            /* внутри пропусков */
#define OUT 0            /* снаружи пропусков */

/* читает строки из файла, а потом записывает их определённым образом 
   первую оставить, вторую - удалить, на месте её - пустая строка и т.д.;
   с перезаписью файла */
main()
{
    void filecopy(FILE *, FILE *);
    FILE *fp, *tfp;
    char line[MAXLINE], *p;
    int state;
    long i, j, nl;
    const char *fname = "file.txt";
        
    if ((fp = fopen(fname, "rb")) == NULL)
        return 1;
    if ((tfp = tmpfile()) == NULL)
        return 2;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, fp)) != NULL) {
        nl++;
        if (i == 0) {
            j++;
            i = j;
            state = OUT;
        } else {
            i--;
            state = IN;
        }    
        fprintf(tfp, "%03d:%s", nl, (state == OUT ? line : "\n"));
    }
    fclose(fp);
    rewind(tfp);
    if ((fp = fopen(fname, "wb")) == NULL)
        return 3;
    filecopy(tfp, fp);
    fclose(tfp);
    fclose(fp);
    return 0;
}

/* filecopy:  копирование файла ifp в файл ofp */
void filecopy(FILE *ifp, FILE *ofp)
{
    int c;
    
    while ((c = getc(ifp)) != EOF)
        putc(c, ofp);
}
может быть можно как-то отрезать от исходного файла часть по окончании работы, т.к. из-за пустых строк файл теряет размер (не будешь же пробелы сохранять), темповый файл - стандарт
классы это уже цпп, я пока с сишником
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
12.12.2008, 10:08     Работа со строками #7
ну если препод так хочет, то можно показать ему следующее
Код
class MyFile : public CFILE
и пусть грызет локти)
только не совсем понятно, что он подразумевает под "переменной типа файл". если структуру FILE .. то возникает другой вопрос - на кой черт огород городить, если все и так огорожено.

Код
class MyFile
{
private:
FILE * fp;
pubilc:
MyFile();
void filecopy(FILE *, FILE *);
~MyFile();
}
но коли переменная объявлена как private, обратиться к ней просто через точку не получится. ибо на то она и private. Видимо товарищ препод добивается от вас еще и написания функция, позволяющих менять это самое fp, например

Код
class MyFile
{
private:
FILE * fp;
pubilc:
MyFile();
void filecopy(FILE *ftc1, FILE *ftc2);
*FILE GetMyFile();
void SetMyFile (FILE* fts);
~MyFile();
}

FILE*MyFile::GetMyFile()
{
return fp;
}

void MyFile::SetMyFile (File * fts)
{
fp=fts;
}
Алексей Студент
0 / 0 / 0
Регистрация: 12.12.2008
Сообщений: 23
12.12.2008, 16:04     Работа со строками #8
Ага, то есть переменные private доступны только для функции, обьявленной в этом же классе? Ногами просьба не бить, просто мы си проходим только месяц, а на допуск к экзамену сказал эту прогу сделать, просто беда(
Так а может в классе обьявить как привейт непосредственно файловую переменную и как паблик функцию, в описание которой запихать потом код, данный acceptom? Так получится?
Accept, небольшая просьба. Можешь сделать комментарии к твоему коду, хотя бы примерные. А то я в нем две трети операторов не знаю, а преподу надо что то сказать)
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
12.12.2008, 17:10     Работа со строками #9
Именно так, приват для того и сделан чтобы функции - не члены класса не имели доступ к этим переменным. Пересадить функции accept'а в класс еще как получится, именно так и надо сделать дабы угодить вашему преподу. Попробуйте сами, компилятора нет под рукой, да и пользительно будет_)
Алексей Студент
0 / 0 / 0
Регистрация: 12.12.2008
Сообщений: 23
12.12.2008, 17:45     Работа со строками #10
Вот хочу пойти наиболее простым путем и в классе обьявить лишь функцию filecopy, как паблик, и переменную ifp, как привейт. Преподу пофиг, что именно сделал в классе, главное чтоб файлофая переменная там была, и к ней ты потом образался.
Код
             
#include <stdio.h>

#define MAXLINE  1000    
#define IN  1            
#define OUT 0            
class cl
{private: FILE*ifp;
public: void filecopy(FILE*,FILE*);
};


void cl::filecopy(FILE *ifp, FILE *ofp)
{ cl z;
    int c;
    
    while ((c = getc(z.ifp )) != EOF)
        putc(c, ofp);
}


main()
{ cl y;
        FILE *fp, *tfp;
    char line[MAXLINE], *p;
    int state;
    long i, j, nl;
    const char *fname = "file.txt";
        
    if ((fp = fopen(fname, "rb")) == NULL)
        return 1;
    if ((tfp = tmpfile()) == NULL)
        return 2;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, fp)) != NULL) {
        nl++;
        if (i == 0) {
            j++;
            i = j;
            state = OUT;
        } else {
            i--;
            state = IN;
        }    
        fprintf(tfp, "%03d:%s", nl, (state == OUT ? line : "\n"));
    }
    fclose(fp);
    rewind(tfp);
    if ((fp = fopen(fname, "wb")) == NULL)
        return 3;
    y.filecopy(tfp, fp);
    fclose(tfp);
    fclose(fp);
    return 0;
}
Так вот, хочу сразу в конструторе filecopy прописать некую классовую переменную, и с помощью её же через точку в этом же конструкторе обращаться к ifp. Это возможно? Вот что то написал.
При компиляции данного кода ошибок не выдает, лишь одно предупреждение
warning C4700: local variable 'z' used without having been initialized
Но программа не работает. Наверное раннее описанное мной предложение все же технически невозможно)
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
12.12.2008, 20:54     Работа со строками #11
вот смотри. у тебя функция filecopy является членом класса cl, стало быть она уже имеет ссылку на один объект этого класса, для которого функция вызывается. и в качестве параметра она по идее должна бы получать объект того же класса. Полшага до переопрееления операторов, так сказать. думаю с этим вы еще столкнетесь.

У вас же получается что функция хоть и является методом класса, но к приватной его части никак не обращаяется.

И уж если городить огород, то надо бы прописать конструктор, функции о которых я упоминал выше, и работать уже с объектами вашего класса, а не со стандартными структурами FILE

Добавлено через 41 минуту 15 секунд
в функции accept, есть неточность. ибо не j++ а j=1.

ну и вот что в итоге
Код
#include <stdio.h>

#define MAXLINE  1000    
#define IN  1            
#define OUT 0 
           
class Cl{
private: 
	FILE*ifp;
public: 
	FILE* GetCl();
	int SetCl (FILE* fts);
	void filecopy(Cl z);
};


void Cl::filecopy(Cl z)
{
    int c;
     while ((c = getc(z.ifp )) != EOF)
        putc(c, ifp);
}

FILE* Cl::GetCl()
{
	return ifp;
}
//это по сути конструктор с параметром
int Cl::SetCl (FILE * fts)
{
	if(fts==NULL)
		return 0;
	else
	{
		ifp=fts;
		return 1;
	}
}

main()
{ Cl ffile, tfile;
    char line[MAXLINE], *p;
    int state;
    long i, j, nl;
    const char *fname = "file.txt"; // отсюда читаем
    const char *tname = "temp.txt"; // сюда пишем

        //file.txt должен существовать
    if ((ffile.SetCl(fopen(fname, "rb"))) == NULL)
        return 1;
//temp.txt если не существует - будет создан
    if ((tfile.SetCl(fopen(tname, "wb"))) == NULL)
        return 2;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, ffile.GetCl())) != NULL) {
        nl++;
        if (i == 0) {
//вот тут была ошибка, иначе читалось только две строки. потом j=3, i=2 и все ..
            j=1;
            i = j;
            state = OUT;
        } else {
            i--;
            state = IN;
        }    
        fprintf(tfile.GetCl(), "%03d:%s", nl, (state == OUT ? line : "\n"));
    }
    fclose(ffile.GetCl());
    fclose(tfile.GetCl());
    return 0;
}
проверил. работает.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
12.12.2008, 23:20     Работа со строками #12
//вот тут была ошибка, иначе читалось только две строки. потом j=3, i=2 и все ..
j=1;
наоборот у меня было без ошибок ты переделал с ошибкой, задание прочитай


Код
 
#include <stdio.h>

#define MAXLINE  1000    /* максимальная длина строки */
#define IN  1            /* внутри пропусков */
#define OUT 0            /* снаружи пропусков */

/* читает строки из файла, а потом записывает их определённым образом 
   первую оставить, вторую - удалить, на месте её - пустая строка и т.д.;
   с перезаписью файла */
main()
{
    void filecopy(FILE *, FILE *); // функция будет использоваться в этой области
    FILE *fp, *tfp;
    char line[MAXLINE], *p;
    int state;
    long i, j, nl;
    const char *fname = "file.txt";
        
    if ((fp = fopen(fname, "rb")) == NULL)
        return 1;
    if ((tfp = tmpfile()) == NULL)
        return 2;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, fp)) != NULL) { // NULL будет когда файл закончится
        nl++; // считает каждую строку
        if (i == 0) { // пока i > 0 вставлять пустые строки
            j++; // сколько пустых строк вставлять на этот раз (должно расти по условию)
            i = j; // ставит верхнюю границу, которую снижает до нуля
            state = OUT; // флаг - выводить строку
        } else {
            i--; // сколько ещё пустых строк осталось вывести
            state = IN; // флаг - скрыть строку
        }
        // флаг управляет выводом:
        // что вывести с номером? строку или пустую строку
        fprintf(tfp, "%03d:%s", nl, (state == OUT ? line : "\n"));
    }
    fclose(fp);
    rewind(tfp); // переводит указатель темпового файла в начало, т.к. туда писались строки
    if ((fp = fopen(fname, "wb")) == NULL) // файл может иметь только право на чтение, проверит
        return 3;
    filecopy(tfp, fp);
    fclose(tfp); // стирает темповый файл
    fclose(fp);
    return 0;
}

/* filecopy:  копирование файла ifp в файл ofp */
void filecopy(FILE *ifp, FILE *ofp)
{
    int c;
    
    while ((c = getc(ifp)) != EOF)
        putc(c, ofp);
}
Добавлено через 7 минут 40 секунд
const char *tname = "temp.txt"; // сюда пишем
в каталоге может быть запрет на изменение списка файлов

//temp.txt если не существует - будет создан
не будет создан

и программу закинуть в такой каталог можно - моя сработает а твоя завалится

Добавлено через 4 минуты 6 секунд
и ещё там может лежать файл temp.txt в котором уже может быть что-то важное (от другой программы например твоей же такой же)

Добавлено через 1 минуту 14 секунд
так что сначала у себя в голове ошибки исправь

Добавлено через 11 минут 18 секунд
//вот тут была ошибка, иначе читалось только две строки
всё там правильно
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
13.12.2008, 00:08     Работа со строками #13
оххо. сколько агрессии. accept, давай пиписьками меряться не будем, а? Я всего лишь хотел помочь автору. Ошибки в j++ действительно нет, ошибка тут:
Код
fprintf(tfp, "%03d:%s", nl, (state == OUT ? line : "\n"));
, ибо не каждую итерацию цикла каретка смещается на новую строку, потести - увидишь.

Автору удачи.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.12.2008, 01:40     Работа со строками #14
давай пиписьками меряться
мне вообще пофиг это тебя заботит

Я всего лишь хотел помочь автору.
и переделал код с ошибкой, медвежья услуга, лучше у себя ошибки поищи

ибо не каждую итерацию цикла каретка смещается на новую строку
потести увидишь? а может ты потестишь, получишь ошибку и выложишь сюда

\r перед \n пусть добавит и то, если потребуется

Добавлено через 52 минуты 43 секунды
я нашёл причину, перешёл в виндовс и скомпилировал в bc3.1, не работает даже консоль
но у меня есть lcc и я написал код в соответствии стандарту ANSI (это 89 год), потому когда я применил lcc для компиляции, сработала как и консоль так и запись в файл и даже без \r
а в bc3.1 не сработала вообще конструкция ?:
потому тебе кажется что там ошибка
Алексей Студент
0 / 0 / 0
Регистрация: 12.12.2008
Сообщений: 23
13.12.2008, 03:45     Работа со строками #15
FOLKEN, вот в твоем коде заменил фнейм и тнейм на имя файла 1.тхт, лежащего у меня в папке проекта.
Код
#include <stdio.h>

#define MAXLINE  1000    
#define IN  1            
#define OUT 0 
           
class Cl{
private: 
	FILE*ifp;
public: 
	FILE* GetCl();
	int SetCl (FILE* fts);
	void filecopy(Cl z);
};


void Cl::filecopy(Cl z)
{
    int c;
     while ((c = getc(z.ifp )) != EOF)
        putc(c, ifp);
}

FILE* Cl::GetCl()
{
	return ifp;
}

int Cl::SetCl (FILE * fts)
{
	if(fts==NULL)
		return 0;
	else
	{
		ifp=fts;
		return 1;
	}
}

main()
{ Cl ffile, tfile;
    char line[MAXLINE], *p;
    int state;
    long i, j, nl;
    const char *fname = "file.txt"; 
    const char *tname = "temp.txt"; 

            if ((ffile.SetCl(fopen("1.txt", "rb"))) == NULL)
        return 1;

    if ((tfile.SetCl(fopen("1.txt", "wb"))) == NULL)
        return 2;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, ffile.GetCl())) != NULL) {
        nl++;
        if (i == 0) {

            j=1;
            i = j;
            state = OUT;
        } else {
            i--;
            state = IN;
        }    
        fprintf(tfile.GetCl(), "%03d:%s", nl, (state == OUT ? line : "\n"));
    }
    fclose(ffile.GetCl());
    fclose(tfile.GetCl());

    return 0;
    
}
Но прога у меня лишь стирает все содержимое из 1.тхт, и ничего туда не пишет.
Кстати функция файлкопи у тебя описана, но в мейне не вызывается. Так и должно быть?
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
13.12.2008, 04:20     Работа со строками #16
вместо j=1 надо j++, accept тут совершенно прав. И посмотри на свой код. ты открываешь файл 1.txt а пишешь в temp.txt

filecopy как-то и не особо нужна оказалась. Если обязательно нужно ее использовать - бери пример accept'a, если нужен пример с классами - можешь взять вот это (теперь точно все работает как надо)

Код
#include <stdio.h>

#define MAXLINE  1000    
#define IN  1            
#define OUT 0 
           
class Cl{
private: 
	FILE*ifp;
public: 
	FILE* GetCl();
	int SetCl (FILE* fts);
	void filecopy(Cl z);
};


void Cl::filecopy(Cl z)
{
    int c;
     while ((c = getc(z.ifp )) != EOF)
        putc(c, ifp);
}

FILE* Cl::GetCl()
{
	return ifp;
}

int Cl::SetCl (FILE * fts)
{
	if(fts==NULL)
		return 0;
	else
	{
		ifp=fts;
		return 1;
	}
}

main()
{ Cl ffile, tfile;
    char line[MAXLINE], *p;
    long i, j, nl;
    const char *fname = "file.txt"; 
    const char *tname = "temp.txt"; 
  
    if ((ffile.SetCl(fopen(fname, "rb"))) == NULL)
        return 1;

    if ((tfile.SetCl(fopen(tname, "wb"))) == NULL)
        return 2;
    i = j = nl = 0;
    while ((p = fgets(line, MAXLINE, ffile.GetCl())) != NULL) 
	{
        nl++;
        if (i == 0) {
            j++;
            i = j;
			fprintf(tfile.GetCl(), "%03d: %s\n", nl, line);
        } else {
            i--;
			fprintf(tfile.GetCl(),"%03d: \r\n",nl);
        }    
    }
    fclose(ffile.GetCl());
    fclose(tfile.GetCl());
    return 0;
}
Алексей Студент
0 / 0 / 0
Регистрация: 12.12.2008
Сообщений: 23
13.12.2008, 09:01     Работа со строками #17
Спс, это пример работает.
Остались два небольших вопроса.
В файле, в который прога записывает результат, после строк, которые остаются(1,3,6 и т.д) печатаются три пустых прямоугольника(непечатных символа). Это как нибудь решается?
И еще, можно сделать так, чтобы прога выдавала результат в тот же файл, из которого брала исходные строки, или можно только в новый?
Так, первый вопрос решил сам просто убрал из этой строки /n.
Код
fprintf(tfile.GetCl(), "%03d: %s\n", nl, line);
Остался вопрос про запись в тот же файл, из которого взяты исходные данные.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.12.2008, 12:18     Работа со строками #18
качайте нормальный компилятор (по стандарту он должен читать из файла перенос строки какой бы он ни был и переводить его в \n, а \n при выводе переводить в перевод строки родной для системы, даже если он двойной)
http://www.q-software-solutions.de/pub/lccwin32.exe

очень интересно это после супер-кода temp.txt остаётся на диске ?

Код
"%03d: %s\n", nl, line);
зря так сделал - поменял смысл, в строке уже есть \n когда она попадает в line из файла (fgets не отбрасывает конец строки)
а так это и не ты сделал, это опять FOLKEN

FOLKEN не трогай мой код, ты не шаришь, ты какого хера темповый файл заменил на свой ? который в итоге как мусор болтается после работы проги
и возврат каретки можно не делать, т.к. это получается лишнее действие (ненужное то есть)
FOLKEN
 Аватар для FOLKEN
21 / 20 / 3
Регистрация: 03.12.2008
Сообщений: 86
13.12.2008, 12:56     Работа со строками #19
Автор, юзай вышеописанную filecopy.

accept, с вами разговор окончен, всего хорошего
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.12.2008, 13:17     Работа со строками
Еще ссылки по теме:

Работа со строками C++
C++ Работа со строками
Работа со строками C++
Работа со строками C++
Работа с строками C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.12.2008, 13:17     Работа со строками #20
lcc не компилит с++

борланд не может скомпилить

Код
#include <iostream>

using namespace std;
main()
{
    cout << "Hello, world!" << endl;
    return 0;
}
с вами разговор окончен, всего хорошего
пиши свой код

мой код работает без изменений классы туда встроить можно легко поищи кого-нибудь более продвинутого, FOLKEN добавляет ошибки а потом будет говорить это не мой код это код accepta
от тебя требовалось то прикрутить классы без изменений кода, а ты даже с этим не справился
учи стандарты а не компиляторы с conio и прочей фигнёй
Yandex
Объявления
13.12.2008, 13:17     Работа со строками
Ответ Создать тему
Опции темы

Текущее время: 07:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru