4 Replies - 4735 Views - Last Post: 07 November 2011 - 07:23 PM Rate Topic: -----

#1 Okysho   User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 96
  • Joined: 09-February 11

Splice array, and reverse half

Posted 07 November 2011 - 01:33 PM

The problem I'm stuck on seems a bit easy, but for some reason I've run into a problem that's beyond my knowledge.

As the title states, I've been tasked to read a line from a file, reverse the first half then stick it on the end:

If that sounded a bit confusing, sample I/O:

abcdef -> defcba

It should be able to handle odd-numbered lines also:

abcdefg -> defgcba

As well as numbers, but since chars are ints it shouldn't be a problem.

Here's where the problem lies. In running the program I get this as output for the first sample input I provided:

?_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_??_???_? ???_?`?_?
Abort trap

Yeah, that's an abort trap at the end...

here's my current code:

/*
 *  Lab6a.c
 *  
 *
 *  Created by Okysho Kenyaku on 11-11-06.
 *  Copyright 2011 Idome Inc. All rights reserved.
 *
 */


# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main(int argc, char *argv[]){
	
	FILE*fptr;
	char line [BUFSIZ];
	char end[50];
	char rev[50];
	int i, j, k, count;
	int command =0;
	
	
	if (argc != 2) 
	{
		printf("Requires valid file name.\n");
		return(-1);
	}
	
	else{
		
		fptr = fopen ( argv[1],"r" ) ;
		if( fptr == NULL )
		{
			printf ( "Cannot find file \n" ) ;
			return(-1);
		}

		else
		{
			while ( fgets ( line, sizeof line, fptr ) != NULL )
			{
				if ((BUFSIZ % 2) ==0) 
				{
						
					j =0;
					
					for (i = (sizeof line / 2); i < sizeof (BUFSIZ /2); i++) 
					{
						end[j] = line[i];
						j++;
					}
					
					count = j;
					//reverse array
					for ( i = 0 ; i < j ; i++ )
					{
						rev[count] = line[i];
						count--;
					}
					//append first half on line onto end
					for (i = j; i < BUFSIZ; i++) {
						end[i] = rev[k];
						k++;
					}
					
					for (i =0; i< BUFSIZ; i++)
					{
					printf("%c", end[i]);
					}
					
					printf("\n");
				}
					
				else
				{	
						j =0;
						
						for (i = (sizeof line / 2); i < sizeof ((BUFSIZ /2) +1); i++) 
						{
							end[j] = line[i];
							j++;
						}
						
						count = j;
						//reverse array
						for ( i = 0 ; i < (j -1) ; i++ )
						{
							rev[count] = line[i];
							count--;
						}
						//append first half on line onto end
						for (i = j; i < BUFSIZ; i++) {
							end[i] = rev[k];
							k++;
						}
						
						for (i =0; i< BUFSIZ; i++)
						{
							printf("%c", end[i]);
						}
						
						printf("\n");
					
					
				}
			}	
		}
	}
}




The output is actually supposed to print to a file, but for debugging purposes I'm printing to the console.

Thanks in advance

~Oky

Is This A Good Question/Topic? 0
  • +

Replies To: Splice array, and reverse half

#2 blackcompe   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1159
  • View blog
  • Posts: 2,547
  • Joined: 05-May 05

Re: Splice array, and reverse half

Posted 07 November 2011 - 03:39 PM

Next time please specify the arguments that your program requires.

for (i = (sizeof line / 2); i < sizeof (BUFSIZ /2); i++) {
                    end[j] = line[i];
                    j++;
                }



Your setting i to 25, since line is an array of 50 chars. So you start writing at end[25] and that's obviously not correct. sizeof gives you the size of the array, not the actual length of the string. Since fgets appends the NULL character at the end of the string, you can
call strlen to get the string length.

I was having some trouble with fgets and strlen.

while ( fgets ( line, sizeof line, fptr ) != NULL ) {


fgets kept appending a newline character to line. I'd suggest using fscanf.

while( fscanf(fptr, "%s", line) >= 0 ) {


gcc's fscanf appends a NULL onto the buffer (I don't know about others).

To get the second half of the line:

while( fscanf(fptr, "%s", line) >= 0 ) {
                int len = strlen(line);
                int r, s;
                for(r = 0, s = len/2; s < len; r++, s++) {
                    end[r] = line[s];
                }
                end[r] = NULL;
                printf("end = %s\n", end);



To reverse the first half of the line, you have:

//reverse array
                for ( i = 0 ; i < j ; i++ ) {
                    rev[count] = line[i];
                    count--;
                }



Here's how to do it:

for(r = 0, s = len/2-1; s >= 0; r++, s--) {
    rev[r] = line[s];
}
rev[r] = NULL;



And, finally to concatenate the end buffer and rev buffer:

int endLen = strlen(end);
int revLen = strlen(rev);
char res[endLen+revLen];

for(i = 0; i < endLen; i++)
    res[i] = end[i];
for(i = 0; i < revLen; i++)
    res[endLen+i] = rev[i];
res[endLen+i] = NULL;

printf("result = %s\n", res);



You need to release your resources by calling fclose(FILE*).
Was This Post Helpful? 0
  • +
  • -

#3 Okysho   User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 96
  • Joined: 09-February 11

Re: Splice array, and reverse half

Posted 07 November 2011 - 04:17 PM

Big help, yeah I forgot to put an fclose...

I should have thought about using fscanf, usually I avoid it since I'm reading a full line and fscanf stops at the first white space it encounters, but it makes things a lot easier.

I feel a bit like an idiot for not doing my loops the way you did, it's so obvious it hurts.

There's just one small problem now though. I've added the segment to write to the file and now it runs a segmentation fault.

Here's the updated code:

/*
 *  Lab5a.c
 *  
 *
 *  Created by Okysho Kenyaku on 11-11-06.
 *  Copyright 2011 Idome Inc. All rights reserved.
 *
 */


# include <stdio.h>
# include <stdlib.h>
# include <string.h>

int main(int argc, char *argv[]){
	
	FILE*fptr;
	FILE*fptr2;
	char line [BUFSIZ];
	char end[50];
	char rev[50];
	char res[strlen(end)+strlen(rev)];
	int i, j, k, count;
	int command =0;
	
	
	if (argc != 2) 
	{
		printf("Requires valid file name.\n");
		return(-1);
	}
	
	else{
		
		fptr = fopen ( argv[1],"r" ) ;
		if( fptr == NULL )
		{
			printf ( "Cannot find file \n" ) ;
			return(-1);
		}

		else
		{
			while ( fscanf(fptr, "%s", line) >= 0 )
			{
				if ((BUFSIZ % 2) ==0) 
				{
						
					j =0;
					
					for (j = 0, i = (strlen(line)/2); i < strlen(line); j++, i++) 
					{
						end[j] = line[i];
					}
					
					count = j;
					//reverse array
					for(i = 0, count = (strlen(line)/2-1); count >= 0; i++, count--)
					{
						rev[count] = line[i];
					}
					rev[count] = '\0';
					//append first half on line onto end
					for (i = j; i < strlen(line); i++) {
						end[i] = rev[k];
						k++;
					}
					
					for(i = 0; i < strlen(end); i++)
					{
						res[i] = end[i];
					}
					for(i = 0; i < strlen(rev); i++)
					{
						res[strlen(end)+i] = rev[i];
					}
					res[strlen(end)+i] = '\0';
					
					//open to re-write to file
					fptr = fopen ( argv[1],"w" ) ;
					if( fptr == NULL )
					{
						printf ( "Cannot find file \n" ) ;
						return(-1);
					}
					else {
						fprintf(fptr2, "%s\n", res);

					}

					fclose(fptr);
				}
					
				else
				{	
					while ( fscanf(fptr, "%s", line) >= 0 )
					{
						if ((BUFSIZ % 2) ==0) 
						{
							
							j =0;
							
							for (i = strlen(line); i < ((strlen(line) /2) +1); i++) 
							{
								end[j] = line[i];
								j++;
							}
							
							count = j;
							//reverse array
							for(i = 0, count = (strlen(line)/2-1); count >= 0; i++, count--)
							{
								rev[count] = line[i];
							}
							rev[count] = '\0';
							
							//append first half on line onto end
							for (i = j; i < strlen(line); i++) {
								end[i] = rev[k];
								k++;
							}
								 
							for(i = 0; i < strlen(end); i++)
							{
								res[i] = end[i];
							}
							for(i = 0; i < strlen(rev); i++)
							{
								res[strlen(end)+i] = rev[i];
							}
							res[strlen(end)+i] = '\0';
							
							//open to re-write to file
							fptr = fopen ( argv[1],"w" ) ;
							if( fptr == NULL )
							{
								printf ( "Cannot find file \n" ) ;
								return(-1);
							}
							else {
								fprintf(fptr2, "%s\n", res);
								
							}
							
							fclose(fptr);
						}
					}
				}	
			}
		}
	}
}



Was This Post Helpful? 0
  • +
  • -

#4 blackcompe   User is offline

  • D.I.C Lover
  • member icon

Reputation: 1159
  • View blog
  • Posts: 2,547
  • Joined: 05-May 05

Re: Splice array, and reverse half

Posted 07 November 2011 - 05:18 PM

Your right about the white space, I didn't see that. Cprogramming.com confirmed what I was saying about fgets appending a newline (under Using Strings).

A few things:

(1) It's best to call strlen(line) once and save to a variable which can be used throughout the program.

(2) You have:

j =0;
            for (j = 0, i = (strlen(line)/2); i < strlen(line); j++, i++) {
                end[j] = line[i];
            }



That first assignment is unnecessary since you initialize it in the for loop.

(3) This is what you had before and it's wrong. It's corrupting the final result when I run your updated program.

count = j;
            //reverse array
            for(i = 0, count = (strlen(line)/2-1); count >= 0; i++, count--) {
                rev[count] = line[i];
            }
            rev[count] = '\0';



Specifically, look at this:

count = (strlen(line)/2-1);
rev[count] = line[i];



Your not writing at the beginning of the array. I showed you how to fix it in my last post. I don't want to jump the gun, but I think the following loops may be wrong to or at least following different logic than what I showed you which was:

---------------
( a ) Get the second half of the line into an array
( b ) Get the first half (reversed) of the line into an array
( c ) Concatenate the arrays
---------------

(4) Once your done reading the file, you need to close it. You didn't close the file you were reading from. Likewise for the file you write to.

(5) Your trying to write to the wrong file

//open to re-write to file
fptr = fopen ( "output.txt","w" ) ;
if( fptr == NULL ) {
    printf ( "Cannot find file \n" ) ;
    return(-1);
} else {
    fprintf(fptr2, "%s\n", res);
    fclose(fptr);
}
}



fptr is the file handle for the file to be written, yet you write to fptr2, which is why your getting a seg fault error.

This post has been edited by blackcompe: 07 November 2011 - 05:19 PM

Was This Post Helpful? 0
  • +
  • -

#5 jimblumberg   User is offline

  • member icon

Reputation: 5916
  • View blog
  • Posts: 17,932
  • Joined: 25-December 09

Re: Splice array, and reverse half

Posted 07 November 2011 - 07:23 PM

Also don't forget that, if fgets stops at the end of line character, the end of line character is included in the resulting string.

Jim
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1