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


Автор: apook 4.1.2007, 14:11
ажет ли мне кто нибудь почему программа не работает как надо,
а то я запарился уже компелировать.

 Программа для замены в текстовом файле

На bcc32 компелирую:
    прога работает, но ...
    1. если я увеличиваю слово "на которое меняю" то программа нач
    инает работать через раз(точнее просто зависает),  причем  чем
    дли нее слово "на которое меняю" тем меньше шансов что все про
    йдет как надо, но даже при вылете можно обнаружить что  задача
    выполнена.
    2. Смотри пункт 1

На tсс компелирую:
    прога не работает, но ...
    1. Тот-раз работала. не помню че сделал что перестала.
    2. Она все-же коипилируется без ошибок но звисает сразу
    3. Убрав из кода все(именнно все) free( );  прога  выполнялась
    но в конце было сообщение что-то там  Null Pointer Assignment,
    но опять-же больше не повторяется
   
Я подозреваю malloc realloc особенно второй но не в курсе что  там
за нюансы, да и по мелочи какие-то косячки
Код
 
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#include "string.h"


long *fcalc( FILE *f )
{
char ch;
long i, j, c, *x;
x=( long * ) malloc ( 2 );
x[0]=0;
x[1]=0;
fseek( f, 0, SEEK_SET );

for( i=0, j=0, c=0; ; i++ )
{
    ch =fgetc( f );
    if( ch =='\n' || ch ==EOF || ch =='\0' )
    {
        if( i >c ) c =i;
        if( ch==EOF && i==0 ) break;
        j++;
        i=0;
        }
    if( ch==EOF ) break;
    }

x[0]=j; /*количество строк */
x[1]=c; /*длина самой длинной строки*/
return x;
}


long *finds( char *str1, char *str2 )
{
const int len1=strlen(str1), len2=strlen(str2);
int i=0, j=0, wi=0, ex=0, r=-1;
long *y;
y =( long *  ) malloc ( 2 );

y[0] =-1;
y[1] =-1;

if( len1 >=len2 )
{
    for( i=0; i <len1; i++ )
    {
        wi =i;
        while( j <len2 )
        {
            if( str1[wi] ==str2[j] )
            {
                if( r <0 ) r = wi;

                if( j == (len2 -1) )
                {
                    ex =1;
                    break;
                    }

                j++;
                wi++;
                }
           else
           {
                r =-1;
                j =0;  
                break; 
                }
            }
         if( ex==1 ) break;
         }
    y[0] =r;
    y[1] =wi;
    }
return y; // Возвращает первое и последнее вхождение
}


void main()
{
long *x, *y;
int i=0, j=0, c=0, q=0, p=0;
char s[50], t[50], fname_in[50], fname_out[50], *str=NULL, *Temp=NULL;
FILE *f, *fd;

x=( long * ) malloc ( 2 );
y=( long * ) malloc ( 2 );


strcpy( fname_in, "Text.txt" );
strcpy( fname_out, "Text.$$$" );

strcpy( s, "abc"  ); // <-- Заменять сочетание 'abc'
strcpy( t, "Hello!"  ); // --> на сочетание 'Hello!'

if( (f=(fopen( fname_in, "r" ))) !=NULL );
else
{
    perror( "Error reading \n");
    exit(1);
    }

if( (fd=(fopen( fname_out, "w+" ))) !=NULL );
else
{
    perror( "Error reading \n");
    exit(1);
    }
    
y =fcalc( f );    
if( y[0] ==0 )
{
    printf( "File Length of zero: %s", fname_in );
    exit(1);
    }    

//Память под переменные ...
if( (str = (char *) malloc(y[1]-strlen(s)+strlen(t))) == NULL)
{
    printf("Not enough memory to allocate buffer\n");
    exit(1);  /* terminate program if out of memory */
    }

if( (Temp = (char *) malloc (y[1]-strlen(s)+strlen(t))) == NULL)
{
    printf("Not enough memory to allocate buffer\n");
    exit(1);  /* terminate program if out of memory */
    }
//..

fseek( f, 0, SEEK_SET );
// ------------------------
for( p=0, y[1]++; !feof( f ); p++  )
{
    fgets( str, y[1], f );

    for( ; ;)
    {
        x=finds( str, s );

    if( x[0] ==-1 || x[1] ==-1 ) break;
        else 
    {
            /* Если удалить этот участок то программа будет заменять все встреченные сочетания
               символов заданные в строке s на символы заданные в строке t, а не слово s на сл
               ово t  
            
            if( (x[0] ==0) && ((str[x[1]+1] ==' ') || (str[x[1]+1] =='\n') || (str[x[1]+1] =='\0')) );
            else if( ((str[x[0]-1] ==' ') || (str[x[0]-1] =='\t')) && ((str[x[1]+1] ==' ') || (str[x[1]+1] =='\n')
            || (str[x[1]+1] =='\0')) );
            else break;
            // ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^       
*/
            if( (Temp = (char *) realloc (Temp, strlen(str)-strlen(s)+strlen(t)+1)) == NULL )
            {
                 printf("Not enough memory to allocate buffer\n");
                 exit(1);
                 }
            for( i=0, c=0; i <x[0]; i++, c++ )
                 Temp[i]=str[c];

            for( j=0; (unsigned)j <strlen(t); j++, i++ )
                 Temp[i]=t[j];

            for( c+=strlen(s); (unsigned)c <strlen(str); i++, c++ )
                 Temp[i]=str[c];
            Temp[i] ='\0';

            str = ( char * ) realloc ( str, strlen(Temp)+1 );

            if( (str = (char *) realloc (str, strlen(Temp)+1)) == NULL )
            {
                 printf("Not enough memory to allocate buffer\n");
                 exit(1);
                 }
            memset( str, NULL, strlen(str) );
        strcpy( str, Temp );
            memset( Temp, NULL, strlen(Temp) );
            }
        }
    fprintf( fd, "%s", str );
    memset( str, NULL, strlen(str) );
    }
// ------------------------


free( Temp );
free( str );

fclose( f );
fclose( fd );

if( remove(fname_in) != 0 )
    perror("remve");

if( rename(fname_out, fname_in) != 0 )
    perror("rename");


free( y );
free( x );
return;
}


Автор: _hunter 4.1.2007, 14:23
ну так берем отладчик и вдумчиво проходим по коду. операцию (в случае необходимости) повторить...

Автор: apook 4.1.2007, 15:30
Если честно не умею пользоваться отладчиком,ведь я недавно программирую
и чисто для себя... Вообще просто  пошагово прохжу , с  остановками, по
коду (миниотладка). Null Pointer Assignment меня уже не первый  раз одо
левает. Пустой указатель. Причем загадочные причины.

Автор: Kuvaldis 4.1.2007, 15:39
apook, 
Код

x=( long * ) malloc ( 2 );

ИМХО, нужно так:
Код

x=( long * ) malloc ( 2 * sizeof(long) );

ты ж выделяешь память только под 2 байта и потом работаешь с памятью под long, которая не была выделена...

Автор: _hunter 4.1.2007, 15:39
не помню как это выгдядело в турбо сях, но помню точно что watch'и там были -- вот туда позагоняй интересующие переменные и посмотри на каком шаге теряеш указатель...

Автор: apook 4.1.2007, 18:08
поменял
x=( long * ) malloc ( 2 );
на
x=( long * ) malloc ( 2 * sizeof(long) );
комиле ин БСС32 и не мог нарадоваться как все работает, пока не
компилировал в tcc там все как раньше.
Так значит надо и str=( char * ) malloc ( 100 * sizeof(char) )
поменять что-ли. В примерах  пишут str=( char * ) malloc ( 20 )
из того-же нелпа?

С дебаггингом напряг, я вообще не  смог его запустить. Запускаю
всякие watch -и а там что-то вроде process not in  assemble это
в Buildere где там кнопка на которой написано Debug блин.

Автор: JackYF 4.1.2007, 18:17
Цитата(apook @  4.1.2007,  18:08 Найти цитируемый пост)
С дебаггингом напряг, я вообще не  смог его запустить. Запускаю
всякие watch -и а там что-то вроде process not in  assemble это
в Buildere где там кнопка на которой написано Debug блин.



Дык а в это время ты прогу пошагово запустил?

Автор: Kuvaldis 4.1.2007, 18:24
apook, 
тискаем кнопку F8... и будет тебе счастье... (пошаговая трассировка)
а вообще  на  наличие ошибок и проверку логики лучше всего отвечает компиляция в Visual Studio smile 

Автор: apook 4.1.2007, 18:39
сейчас подставил и sizeof(char) заработало и в Turbo
благодарю Kuvaldis -а

Пошагово громко сказано
просто getch(); а перед этим printf( переменная )

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