Help with changing char *string to int * string for sorting.

P

Pokerkook

Hello,

If anybody could help me with this I would greatly appreciate it. Or at least
tell me why I get the output of this garbage:

49
49
10
49
52
10

I'm trying to sort integers from a text file. Sorry if my code is bad or way
off base. I am a newbie to the C Language & I am just learning Arrays &
pointers.


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


void Outputdata(char filename[], char theString[]);
void Sortdata(int theString[], int n );

int main()
{
char theString[20000]="";
char filename[20];
int count;
int n=10;

int x[20000];

printf("\nPlease enter Filename: ");
gets(filename); /* user inputs filename */
Outputdata(filename, theString);
*x = atoi(theString);
Sortdata( x, n );
printf("\nAfter the sort, the contents are:\n");

for( count = 0; count < n; count++ )
printf("Count = %d = %.d\n", count, theString[ count ]);

}

void Sortdata( int String[], int n )

{
int index = 0;
int x = 0;
int temp;

while ( x < (n - 1) )
{
index = x + 1;
while ( index < n )
{
if( String[ x ] > String[ index ] )
{
temp = String[ x ];
String[ x ] = String[index];
String[index] = temp;
}
index++;
}
x++;
}
}


void Outputdata(char filename[], char theString[])
{

FILE *fp;

char buf[BUFSIZ+1];
fp = fopen (filename, "r"); /* file is 10 integers on separate lines */

while (fgets(buf, BUFSIZ, fp) != NULL)
{
strcat(theString, buf);
}

printf("\n%s", theString);

fclose(fp);

}
 
A

Al Bowers

Pokerkook said:
Hello,

If anybody could help me with this I would greatly appreciate it. Or at least
tell me why I get the output of this garbage:

49
49
10
49
52
10

I'm trying to sort integers from a text file. Sorry if my code is bad or way
off base. I am a newbie to the C Language & I am just learning Arrays &
pointers.


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


void Outputdata(char filename[], char theString[]);
This function should return a value which can be use
to determine whether or not the file was accessed.
void Sortdata(int theString[], int n );

int main()
{
char theString[20000]="";

using theString is a poor approach in parsing the file.
char filename[20];
int count;
int n=10;

int x[20000];

Since the size of the array is unknown, why not dynamically
allocate space as you need it using function realloc?
You can define a data struct that will a member pointint to
the array and another member keeping a count. See the Example
below.
printf("\nPlease enter Filename: ");
gets(filename); /* user inputs filename */
Function gets very unsafe, use function fgets.
Outputdata(filename, theString);
*x = atoi(theString);
Sortdata( x, n );
printf("\nAfter the sort, the contents are:\n");

for( count = 0; count < n; count++ )
printf("Count = %d = %.d\n", count, theString[ count ]);

}

void Sortdata( int String[], int n )
.........snip,,,,,,,,

You can use function qsort to sort the numbers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct INTARRAY
{
int *num;
size_t count;
} INTARRAY;

int GetDataINTARRAY(const char *filename, INTARRAY *p);
void SortINTARRAY(INTARRAY *p, int (*cmp)(const void *, const void *));
void PrintINTARRAY(INTARRAY *p);
void FreeINTARRAY(INTARRAY *p);
int cmp(const void *v1, const void *v2);

int main(void)
{
char filename[64],*s;
INTARRAY myint = {NULL};

printf("\nPlease enter Filename: ");
fflush(stdout);
fgets(filename, sizeof filename,stdin);
if(s = strrchr(filename,'\n')) *s = '\0';
else while('\n' != getchar());
if(GetDataINTARRAY(filename, &myint))
{
puts("\tUnSorted");
PrintINTARRAY(&myint);
SortINTARRAY(&myint,cmp);
puts("\n\tSorted");
PrintINTARRAY(&myint);
}
else puts("File not Found or Memory Allocation Failure");
FreeINTARRAY(&myint);
return 0;
}

void SortINTARRAY(INTARRAY *p, int (*cmp)(const void *, const void *))
{
if(p->num)
qsort(p->num,(size_t)p->count,sizeof *p->num,cmp);
return;
}

int GetDataINTARRAY(const char *fname, INTARRAY *p)
{
FILE *fp;
int ibuf, *tmp;

if((fp = fopen (fname, "r")) == NULL) return 0;
while(1 == fscanf(fp," %d",&ibuf))
{
tmp = realloc(p->num,(p->count+1)*(sizeof *tmp));
if(tmp == NULL)
{
FreeINTARRAY(p);
return 0;
}
p->num = tmp;
p->num[p->count++] = ibuf;
}
fclose(fp);
return 1;
}

int cmp(const void *v1, const void *v2)
{
const int *i1 = v1;
const int *i2 = v2;

return (*i1<*i2)?-1:(*i1!=*i2);
}

void PrintINTARRAY(INTARRAY *p)
{
size_t i;

for(i = 0; i < p->count; i++)
printf("num[%u] = %d\n",i,p->num);
return;
}

void FreeINTARRAY(INTARRAY *p)
{
free(p->num);
p->num = NULL;
p->count = 0;
return;
}
 
J

Jens.Toerring

Pokerkook said:
I'm trying to sort integers from a text file. Sorry if my code is bad or way
off base. I am a newbie to the C Language & I am just learning Arrays &
pointers.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void Outputdata(char filename[], char theString[]);
void Sortdata(int theString[], int n );
int main()
{
char theString[20000]="";
char filename[20];
int count;
int n=10;

int x[20000];
printf("\nPlease enter Filename: ");

You need either a '\n' at the end of the string or call fflush(),
otherwise the string may not appear.
gets(filename); /* user inputs filename */

Never ever use gets(), this function is nothing than a desaster waiting
to happen. You can't check if the user inputs a file name with more
than 19 characters and if he does gets() will happily write past the
end of the buffer you set aside for 'filename'. Use fgets() instead.
Outputdata(filename, theString);
*x = atoi(theString);

It looks as if you have the impression that atoi() would convert all
numbers in the string into integers and store them successively in
the array 'x'. But that's not what atoi() does: it converts the
first number in the string it finds and returns this number. You
will have to chop up the string into the parts consisting of numbers
and apply atoi() to each of them. Things get a lot easier if you
use strtol() instead of atoi() since it a) lets you do error checking
and b) tells you where it left off, so you can use that knowledge
to figure out where to look for the next number. So you could do
something like (assuming there are only numbers and white-space in
the file and, beware, untested)

size_t i;
int x[ 20000 ];
char *startptr;
char *endptr;

for ( startptr = theString; i < 20000; i++ )
{
x[ i ] = ( int ) strtol( startptr, &endptr, 10 );
if ( startptr == endptr ) /* no number found in file anymore */
break;
startprt = endptr;
}

if ( i >= 20000 )
fprintf( stderr, "Stopped after converting 20000 numbers, "
"there could be more.\n" );
else
fprint( "Got %ld numbers\n", ( long ) ++i );

You could (and for a real program should) even build in more error
checking, i.e. for cases where numbers are too large to be repre-
sented as integers (or even as long integers).
Sortdata( x, n );

Why would you want to sort only the first 'n' numbers and not all
you read in?
printf("\nAfter the sort, the contents are:\n");
for( count = 0; count < n; count++ )
printf("Count = %d = %.d\n", count, theString[ count ]);

While the dot in "%.d" won't hurt it doesn't do anything useful.
And since you promised that main() would return an int you need
here
return 0;
or
return EXIT_SUCCESS;

(but you must include said:
void Sortdata( int String[], int n )
{
int index = 0;
int x = 0;
int temp;
while ( x < (n - 1) )
{
index = x + 1;
while ( index < n )
{
if( String[ x ] > String[ index ] )
{
temp = String[ x ];
String[ x ] = String[index];
String[index] = temp;
}
index++;
}
x++;
}
}

Bubblesort - not very famous for it's speed. Why not use qsort() that
is already built-in into C?
void Outputdata(char filename[], char theString[])
{
FILE *fp;
char buf[BUFSIZ+1];
fp = fopen (filename, "r"); /* file is 10 integers on separate lines */

And what is supposed to happen when the file does not exist or you
don't have permissions to open it, i.e. when fopen() returns NULL?
while (fgets(buf, BUFSIZ, fp) != NULL)
{
strcat(theString, buf);
}
printf("\n%s", theString);

}

You should be more careful here. All this will probably work fine with
your short file, but when you try to use the program with a file that
is longer than the 20000 characters you set aside for 'theString'
suddenly all kind of weird problems will start to appear since you then
are going to write past the end of that buffer.

Once you got that program to work properly you should start to learn
about dynamical memory allocation. That will allow you to read in
files of all lengths (limited only by how much memory your system
is willing to give your program).
Regards, Jens
 
G

Gregory Shearman

You need either a '\n' at the end of the string or call fflush(),
otherwise the string may not appear.

You can always turn off the buffering on the standard output stream using
setvbuf(). It would save a lot of calls to fflush() every time you want to
print something to the controlling terminal.
 
L

Lawrence Kirby

You can always turn off the buffering on the standard output stream using
setvbuf(). It would save a lot of calls to fflush() every time you want to
print something to the controlling terminal.

However buffering is usually a GOOD THING. Try to avoid turning it off if
you can.

Sometimes a better strategy than flushing after you "print" is to flush
just before you input.

Lawrence
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top