Hi,

I have written a program that copies one file to another while making format changes to some lines
The relevant part of the code is the following"

while(fgets (cbuff, 80, f1)!= NULL)
{
        if (  (isdigit(cbuff[5])) && (isdigit(cbuff[11])) && (isdigit(cbuff[17]))  )
        {
        strncpy (c1, cbuff+1, 5);
        c1[5] = '\0';
        strncpy (c2, cbuff+7, 5);
        c2[5] = '\0';
        strncpy (c3, cbuff+13, 5);
        c3[5] = '\0';
        strncpy (c4, cbuff+21, 2);
        c4[2] = '\0';
        fprintf(f2,"%s%s%s%s\n", c1, c2, c3, c4);
        }

        else
        {
        fputs(cbuff, f2);
        }
}

The program works but does the following:

Input:
1 1 2 1
2 1 4 1
3 2 3 2
4 2 5 1
5 3 6 1
6 3 7 1

Output:
1 1 2 1
2 1 4 1
3 2 3 2
4 2 5 1
5 3 6 1
6 3 7 1
3 7 1


The program outputs an additional line with values of string c2, c3 and c4. I dont understand why this is happening?
How can i get rid of this additional line ?

Thanks in advance.

The Input you posted doesn't make sense with the code you posted. The first line after the fgets() is checking characters positions a lot longer then the example input lines you posted.

My guess is that the function you posted is not causing the problem.

I think the spaces got deleted when i posted my question. Here are the inputs & outputs again.

Input:

1     1     2    1
     2     1     4    1
     3     2     3    2
     4     2     5    1
     5     3     6    1
     6     3     7    1

Ouput:

1    1    2 1
    2    1    4 1
    3    2    3 2
    4    2    5 1
    5    3    6 1
    6    3    7 1
    3    7 1

I used VC++ 2008 Express and your program worked ok for me. Are you closing the two files asap to prevent the output file from being updated after the code you posted finished? Or maybe the buffers c1 ... c5 aren't large enough.

1    1    2 1
    2    1    4 1
    3    2    3 2
    4    2    5 1
    5    3    6 1
    6    3    7 1
int main()
{
FILE *f1, *f2;
f1 = fopen("\\tmp\\mel.txt","r");
if(f1 == NULL)
   return 1;
f2 = fopen("tmp.txt","w");
char cbuff[255]= {0};
char c1[80] = {0};
char c2[80] = {0};
char c3[80] = {0};
char c4[80] = {0};
char c5[80] = {0};

while(fgets (cbuff, 80, f1)!= NULL)
{
    if (  (isdigit(cbuff[5])) && (isdigit(cbuff[11])) && (isdigit(cbuff[17]))  )
    {
        strncpy (c1, cbuff+1, 5);
        c1[5] = '\0';
        strncpy (c2, cbuff+7, 5);
        c2[5] = '\0';
        strncpy (c3, cbuff+13, 5);
        c3[5] = '\0';
        strncpy (c4, cbuff+21, 2);
        c4[2] = '\0';
        fprintf(f2,"%s%s%s%s\n", c1, c2, c3, c4);
        }
        else
        {
        fputs(cbuff, f2);
        }
}

fclose(f1);
fclose(f2);
return 0;
}

Wow, thats weird. I am using gcc to compile my code on either a Gentoo Linux or Irix machine and i still get the same problem. I have increased the buffers and yet same behaviour.
Here is part of my actual input file. Can you check if this works ?

@<TRIPOS>MOLECULE
C00071
 7 6 0 0 0
SMALL
NO_CHARGES

@<TRIPOS>ATOM
      1 O1         29.3456    6.3882   17.8044 O.3     1  <1>         0.0000
      2 C2         30.4396    5.7640   17.3918 C.2     1  <1>         0.0000
      3 C3         31.6613    6.2938   17.6193 C.2     1  <1>         0.0000
      4 H4         29.4168    7.2248   18.2697 H       1  <1>         0.0000
      5 H5         30.3544    4.8318   16.8736 H       1  <1>         0.0000
      6 H6         31.7523    7.2258   18.1371 H       1  <1>         0.0000
      7 H7         32.5379    5.7814   17.2819 H       1  <1>         0.0000
@<TRIPOS>BOND
     1     1     2    1
     2     1     4    1
     3     2     3    2
     4     2     5    1
     5     3     6    1
     6     3     7    1

@<TRIPOS>MOLECULE
C00074
 15 14 0 0 0
SMALL
NO_CHARGES

I think the problem is that your function is not checking the line lengths before attempting to check character position 17 -- many of those lines are'nt 17 or more charcters long while others are much longer.

Actually the intention of the program is only to format lines between @<TRIPOS>BOND and @<TRIPOS>MOLECULE.
These are the only lines that match the condition of having a digit at the 5, 11 and 17th position.
The program works perfect except the additional line from c2, c3 and c4.

int main()
{
FILE *f1, *f2;
f1 = fopen("\\tmp\\mel.txt","r");
if(f1 == NULL)
   return 1;
f2 = fopen("tmp.txt","w");
char cbuff[255]= {0};
char c1[80] = {0};
char c2[80] = {0};
char c3[80] = {0};
char c4[80] = {0};
char c5[80] = {0};
int start = 0;
while(fgets (cbuff, 80, f1)!= NULL)
{
    if(!start)
    {
        if( strcmp(cbuff,"@<TRIPOS>BOND\n") == 0)
        {
            start = 1;
        }
        fputs(cbuff, f2);
    }
    else 
    {
        if( cbuff[0] == '\n')
        {
            start = 0;
            fputs(cbuff, f2);
        }
        else
        {
            if (  (isdigit(cbuff[5])) && (isdigit(cbuff[11])) && (isdigit(cbuff[17]))  )
            {
                strncpy (c1, cbuff+1, 5);
                c1[5] = '\0';
                strncpy (c2, cbuff+7, 5);
                c2[5] = '\0';
                strncpy (c3, cbuff+13, 5);
                c3[5] = '\0';
                strncpy (c4, cbuff+21, 2);
                c4[2] = '\0';
                fprintf(f2,"%s%s%s%s\n", c1, c2, c3, c4);
            }
            else
            {
                fputs(cbuff, f2);
            }
        }
    }
}

fclose(f1);
fclose(f2);
return 0;
}

produces this output

@<TRIPOS>MOLECULE
C00071
 7 6 0 0 0
SMALL
NO_CHARGES

@<TRIPOS>ATOM
      1 O1         29.3456    6.3882   17.8044 O.3     1  <1>         0.0000
      2 C2         30.4396    5.7640   17.3918 C.2     1  <1>         0.0000
      3 C3         31.6613    6.2938   17.6193 C.2     1  <1>         0.0000
      4 H4         29.4168    7.2248   18.2697 H       1  <1>         0.0000
      5 H5         30.3544    4.8318   16.8736 H       1  <1>         0.0000
      6 H6         31.7523    7.2258   18.1371 H       1  <1>         0.0000
      7 H7         32.5379    5.7814   17.2819 H       1  <1>         0.0000
@<TRIPOS>BOND
    1    1    2 1
    2    1    4 1
    3    2    3 2
    4    2    5 1
    5    3    6 1
    6    3    7 1

@<TRIPOS>MOLECULE
C00074
 15 14 0 0 0
SMALL
NO_CHARGES

Thanks your solution works. So it was the empty line after the numbers which was the problem.
Also why the else statement (line 46-49). It works fine without it.

Also why the else statement (line 46-49). It works fine without it.

I just didn't take it out of your original post. just delete them if they aren't needed.

This article has been dead for over six months. Start a new discussion instead.