#define MAX_HEIGHT 512
#define MAX_WIDTH 512
typedef struct
{
int lines;
int cols;
int highestValue;
int matrix[MAX_WIDTH][MAX_HEIGHT];
} Pgm;
void getInfo()
{
Pgm pgm;
FILE *f = fopen("pepper.pgm", "r");
bool keepReading = true;
int line = 0, countSpaces = 0, i = 0;
do
{
fgets(buffer, MAX_LINE, f);
if (feof(f))
{
printf("\nCheguei no final do arquivo");
keepReading = false;
break;
}
if (line >= 3)
{
char *values = strtok(buffer, " ");
while (values != NULL)
{
total++;
// printf("values: %d, cols: %d, pgm.matrix[%d][%d], total: %d\n", atoi(values), pgm.cols, i, countSpaces, total);
pgm.matrix[i][countSpaces] = atoi(values);
if (i == pgm.lines && countSpaces == pgm.cols)
break;
countSpaces++;
if (countSpaces == pgm.cols)
{
countSpaces = 0;
i++;
}
values = strtok(NULL, " ");
}
}
line++;
} while (keepReading);
fclose(f);
printf("cols: %d, lines: %d, highest: %d, matrix[0][0]: %d", pgm.cols, pgm.lines, pgm.highestValue, pgm.matrix[0][0]);
}
void resolveMatrix()
{
Pgm pgm;
printf("cols: %d, lines: %d, highest: %d", pgm.cols, pgm.lines, pgm.highestValue);
}
I have this getInfo function that reads a .pgm file and adds the values inside this file to a matrix inside my struct. When i do a printf statement inside such function it prints out the right values that i want. But when i try to do that inside another function it prints out diffent values. I think this has to do with memory addres, but how would i solve this :(
In your resolveMatrix function you are using the struct pgm without initializing it, so it will print random garbage that was on that memory location on the stack before the struct was created.
If you want to use a struct that was created somewhere else, pass a pointer to it as a function parameter:
void resolveMatrix(Pgm *pgm)
{
printf("cols: %d, lines: %d, highest: %d", pgm->cols, pgm->lines, pgm->highestValue);
}
Usage:
Pgm pgm;
// Initialize struct fields here ...
resolveMatrix(&pgm);
Related
I've been trying to split writing to a file with threads and to do so I'm trying to use structs to hold the start and end positions of the file. The code compiles, However, I've been getting a segmentation fault when the code tries to create multiple threads and doesn't execute the thread code. Am I using structs correctly?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_THREADS 100
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct position {
int start;
int end;
};
void *ThreadJob(void *id) //what the thread should do
{
pthread_mutex_lock(&mutex);
struct position *b;
printf("\nstart: %d \nend: %d\n", (*b).start, (*b).end);
double* arrayPtr = malloc( 100000* sizeof(double));
FILE *file;
FILE* nFile; // New file
double n;
nFile = fopen("newTriData1.txt","a");
char line[128]; //the lines of the txt file
file = fopen("TriData1.txt", "r");
long tid;
tid = (long)id;
int count = 0;
while (fgets(line, 128, file)) //gets the lines from the txt file - line by line
{
sscanf(line ," %lf", &arrayPtr[count]); //converts the value on the line into a double to manipulate
count++; //increment the count
}
free(arrayPtr);
while((*b).start<(*b).end){
double x = (sqrt(8*arrayPtr[(*b).start]+1) - 1) / 2; //equation to detect triangular numbers
if (x == floor(x)) //checks if the value has a remainder. The value should be a whole number
{
fprintf(nFile, "\nNumber %s: Triangular\n", line); //if true writes the value and triangular
}
else
{
fprintf(nFile, "\nNumber %s: Not Triangular\n", line);
}
(*b).start++;
}
(*b).start=(*b).end;
(*b).end = ((*b).end + (*b).end);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main (void) //main
{
struct position a;
(a).start=0;
int line_count;
FILE *file;
double count_lines = 1.0;
char check;
double i = 4;
file = fopen("TriData1.txt", "r");
double divider;
check = getc(file);
while (check != EOF)
{
if (check == '\n')
{
count_lines = count_lines + 1;
}
check = getc(file); //take the next character from the file
}
printf("cl: %f", count_lines);
double vo = fmod(count_lines,4); //using fmod to find which number divides the line count into equal parts for the number of threads
if (fmod(count_lines,4) == 0) {
double value1 = count_lines/4;
double value2 = count_lines/4;
double value3 = count_lines/4;
double value4 = count_lines/4;
printf("v1: %f \n v2: %f \n v3: %f \n v4: %f", value1,value2,value3,value4);
divider =4;
line_count = count_lines/4;
(a).end=line_count;
}
else
{
while (fmod(count_lines, i) != 0) //if the value is not divisible by 4 then i will increment until a suitable divider is found
{
i++;
divider = i;
line_count = count_lines/i;
printf("divider: %f", divider);
}
(a).end=line_count;
}
fclose(file); //close file.
printf("There are %f lines in this file\n", count_lines);
printf("\nstart: %d \nend: %d\n", (a).start, (a).end);
pthread_t threads[MAX_THREADS];
int thread;
long threadNum ;
for(threadNum=0; threadNum<divider; threadNum++){
printf("Creating thread %ld\n", threadNum);
thread = pthread_create(&threads[threadNum], NULL, ThreadJob, (void *)threadNum);
if (thread){
printf("ERROR; %d\n", thread);
exit(-1);
}
}
pthread_exit(NULL);
return 0;
}
Almost every line of your code is wrong, but most of your mistakes will just make your program do the wrong thing, not crash entirely. Here's just the mistakes that are making your program crash:
struct position *b;
printf("\nstart: %d \nend: %d\n", (*b).start, (*b).end);
That will probably segfault because you can't dereference an uninitialized pointer.
free(arrayPtr);
while((*b).start<(*b).end){
double x = (sqrt(8*arrayPtr[(*b).start]+1) - 1) / 2; //equation to detect triangular numbers
That might segfault because you can't use memory after you free it. Also, the last line of it will probably segfault because you still never initialized b.
(*b).start++;
}
(*b).start=(*b).end;
(*b).end = ((*b).end + (*b).end);
All of those lines will probably segfault because b still isn't initialized.
Frankly, you should give up on advanced topics like threads for now and work on trying to understand the basics of C.
Hey I have a problem with my code project where I try to create a project that keeps up wit Olympic medals. I have a problem of creating a text file that contains the structure and is named by user. I also have a problem to download the structure.
PROBLEM: I have a problem to make a text file named by user that contains the structure and then download it back to stdout. I don't know how to fix my functions to do this correctly. Now my function save_file can't even produce the file.
Example if the input:
A Canada
A USA
M USA 2 1 1
M Canada 0 0 1
M USA 1 3 1
M USA -1 0 0
L
W medals
Q
I have defined my structure this way:
typedef struct Olympia
{
char* country;
int gold;
int silver;
int bronze;
}Olympia;
Then I have a function that adds country
int add_country(struct Olympia* data, char* str, int i)
{
if (str[0] == '\0') //checking that input is correct
{
printf("Error! Try again!\n");
}
else
{
data[i].country = malloc(strlen(str) + 2); //allocating memory for country name
strcpy(data[i].country, str); //adding country to database
data[i].gold = 0; //setting medals to zero
data[i].silver = 0;
data[i].bronze = 0;
i++;
}
return i;
}
Next I add medals to the each country
int update_medals(struct Olympia* data, char* str, int add_gold, int add_silver, int add_bronze, int i)
{
int a = 0;
int b = 0;
if (str[0] == '\0') //checking that input is correct
{
printf("Error! Try again!");
}
else
{
while (a < i)
{
if (strcmp(data[a].country, str) == 0) //adding medals to right country
{
data[a].gold = data[a].gold + add_gold;
data[a].silver = data[a].silver + add_silver;
data[a].bronze = data[a].bronze + add_bronze;
b++;
}
a++;
}
if (b == 0) //and if the country didn't participate to the olympics
{
printf("This country isn't in the Olympics! Try Again!\n");
}
}
}
Next there is print function
int print_data(struct Olympia* data, int i)
{
for (int a = 0; a < i; a++)
{
printf("%s %d %d %d\n", data[a].country, data[a].gold, data[a].silver, data[a].bronze);
}
}
And then there are the two function that doesn't work. What should I do?
Olympia *save_file(Olympia* data, const char* filename, int i)
{
if (strlen(filename) > 100)
{
printf("Filename is too long: Maxium lenght for filename is 100 characters");
return data;
}
char name[100];
int ret = sscanf(filename, "W %s", name);
if (ret != 1)
{
printf("Error! Try again!");
return data;
}
FILE* file = fopen(name, "w");
if (!file)
{
printf("Error saving file! Try again");
return data;
}
int a = 0;
while (data[a].country[0] != 0)
{
fprintf(file, "%s %d %d %d\n", data[a].country, data[a].gold, data[a].silver, data[a].bronze);
a++;
}
fclose(file);
return 0;
}
int load_file(struct Olympia* data, char* filename, int i)
{
int a = 0;
FILE* file = fopen(filename, "r");
if (!file)
{
printf("Error opening file! Try again");
}
struct Olympia* arr = malloc(sizeof(Olympia));
while (fscanf(file, "%s %d %d %d", data[a].country, data[a].gold, data[a].silver, data[a].bronze))
{
i++;
a++;
arr = realloc(arr, sizeof(Olympia) * (i + 2));
}
arr[a].country[0] = 0;
fclose(file);
return arr;
}
And the main function
int main(void)
{
char command;
int gold = 0;
int silver = 0;
int bronze = 0;
int i = 0;
char* line = (char*)malloc((100) * sizeof(char)); //allocating memory for one stdin line
char* countryname = (char*)malloc(20 * sizeof(char)); // allocating memory for country name
char* filename = (char*)malloc(100 * sizeof(char));
struct Olympia* countrydata = malloc(sizeof(struct Olympia) * 1); //allocating memory for structure
line = fgets(line, 100, stdin);
while(1)
{
sscanf(line, "%c %s %d %d %d", &command, countryname, &gold, &silver, &bronze);
switch (command)
{
case 'A':
i = add_country(countrydata, countryname, i);
countrydata = realloc(countrydata, sizeof(struct Olympia) * (i + 1));
break;
case 'M':
update_medals(countrydata, countryname, gold, silver, bronze, i);
break;
case 'L':
print_data(countrydata, i);
break;
case 'W':
save_file(countrydata, filename, i);
break;
case 'O':
i = load_file(countrydata,filename, i);
break;
case 'Q':
free(line);
free(countryname);
free(countrydata);
return(EXIT_SUCCESS);
}
line = fgets(line, 100, stdin);
if (line == NULL)
{
free(line);
free(countryname);
free(countrydata);
return(EXIT_SUCCESS);
}
}
}
You call save_file(countrydata, filename, i); without having set filename. Change to save_file(countrydata, line, i); since for whatever reason you expect the command character W to precede the name.
Then in save_file() the condition in while (data[a].country[0] != 0) is unusable, since the data element after the last one is not initialized. Use while (a < i) instead.
I am coding a song database. For now, the data of 2 songs are stored in a text file, one struct field per line. I would like to copy the content of the file line by line into an array, and I do not get why the program crashes after calling load(). Is it a problem related to fgets()? Or when I replace '\n' by '\0'?
Here are the interesting parts of the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "functions.h"
int main()
{
int menu;
bool exit = false;
/*char title[256];
char artist[256];
char album[256];*/
int year;
Song **songs = NULL; // base pointer to the array (of pointers to struct)
FILE *f; // pointer to a file structure
int n = 0; // height of array at the beginning (= number of pointers to struct)
int i;
f = fopen("database.txt", "r+");
if(f == NULL)
return 0;
count_songs_db(f, &n); // will modify n (height of array) according to the number of existing songs
printf("n = %d\n", n);
songs = (Song**)malloc(n*sizeof(Song));
load(f, songs, n);
// MENU
for(i = 0 ; i < n ; ++i)
free(songs[i]);
free(songs);
fclose(f);
return 0;
}
functions:
void count_songs_db(FILE *f, int *n) // calculate how many songs there are already in the database.
{
int c, n_lines = 0;
while ((c = getc(f)) != EOF)
if (c == '\n')
++n_lines; // count number of lines
*n = n_lines/6; // 1 song = 6 lines. Changes the height of array accordingly.
rewind(f); // go back to beginning of file, to be able to load the db
}
void load(FILE *f, Song **songs, int n) // load existing songs (in the file) into the array
{
int i;
for(i = 0 ; i < n ; ++i)
{
fgets(songs[i]->title, 256, f); // reads a line of text
songs[i]->title[strlen(songs[i]->title)-1] = '\0'; // to replace \n by \0 at the end // not working?
fgets(songs[i]->artist, 256, f);
songs[i]->title[strlen(songs[i]->artist)-1] = '\0';
fgets(songs[i]->album, 256, f);
songs[i]->title[strlen(songs[i]->album)-1] = '\0';
fscanf(f, "%d\n", &(songs[i]->year)); // use it like scanf
fgets(songs[i]->genre, 256, f);
songs[i]->title[strlen(songs[i]->genre)-1] = '\0';
fscanf(f, "%d:%d\n", &(songs[i]->length.m), &(songs[i]->length.s));
}
for(i = 0 ; i < n ; ++i)
{
printf("Title: %s\n", songs[i]->title);
printf("Artist: %s\n", songs[i]->artist);
printf("Album: %s\n", songs[i]->album);
printf("Year of release: %d\n", songs[i]->year);
printf("Genre: %s\n", songs[i]->genre);
printf("Length: %d:%d\n", songs[i]->length.m, songs[i]->length.s);
}
}
struct:
typedef struct Length {
int m, s;
} Length;
typedef struct Song {
char title[256];
char artist[256];
char album[256];
int year;
char genre[256];
Length length;
} Song;
Thanks for your help.
Edit: I modified the code to use a simple array of struct. Here is the add_song() function and save() function:
void add_song(Song *songs, int *n)
{
printf("Title: ");
read(songs[*n].title, MAX_SIZE); // another function is used instead of scanf(), so the user can enter string with spaces. Also more secure.
printf("Artist: ");
read(songs[*n].artist, MAX_SIZE);
printf("Album: ");
read(songs[*n].album, MAX_SIZE);
printf("Year of release: ");
songs[*n].year = read_long(); // still have to check the user inputs (ie. year has to be between 1900 and 2017)
printf("Genre: ");
read(songs[*n].genre, MAX_SIZE);
printf("Length: \nmin: ");
songs[*n].length.m = read_long();
printf("sec: ");
songs[*n].length.s = read_long();
++(*n);
}
void save(FILE *f, Song *songs, int n) // save song in file
{
fprintf(f, "%s\n%s\n%s\n%d\n%s\n%d:%d\n", songs[n-1].title, songs[n-1].artist, songs[n-1].album, songs[n-1].year, songs[n-1].genre, songs[n-1].length.m, songs[n-1].length.s); // use it like printf. Prints the data in the file.
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct Length {
int m, s;
} Length;
typedef struct Song {
char title[256];
char artist[256];
char album[256];
int year;
char genre[256];
Length length;
} Song;
void count_songs_db(FILE *f, int *n) // calculate how many songs there are already in the database.
{
int c, n_lines = 0;
while ((c = getc(f)) != EOF)
if (c == '\n')
++n_lines; // count number of lines
*n = n_lines / 6; // 1 song = 6 lines. Changes the height of array accordingly.
rewind(f); // go back to beginning of file, to be able to load the db
}
void load(FILE *f, Song *songs, int n) // load existing songs (in the file) into the array
{
int i;
for (i = 0; i < n; ++i)
{
fgets(songs[i].title, 256, f); // reads a line of text
songs[i].title[strlen(songs[i].title) - 1] = '\0'; // to replace \n by \0 at the end // not working?
fgets(songs[i].artist, 256, f);
songs[i].title[strlen(songs[i].artist) - 1] = '\0';
fgets(songs[i].album, 256, f);
songs[i].title[strlen(songs[i].album) - 1] = '\0';
fscanf(f, "%d\n", &(songs[i].year)); // use it like scanf
fgets(songs[i].genre, 256, f);
songs[i].title[strlen(songs[i].genre) - 1] = '\0';
fscanf(f, "%d:%d\n", &(songs[i].length.m), &(songs[i].length.s));
}
for (i = 0; i < n; ++i)
{
printf("Title: %s\n", songs[i].title);
printf("Artist: %s\n", songs[i].artist);
printf("Album: %s\n", songs[i].album);
printf("Year of release: %d\n", songs[i].year);
printf("Genre: %s\n", songs[i].genre);
printf("Length: %d:%d\n", songs[i].length.m, songs[i].length.s);
}
}
int main()
{
int menu;
bool exit = false;
/*char title[256];
char artist[256];
char album[256];*/
int year;
Song *songs = NULL; // base pointer to the array (of pointers to struct)
FILE *f; // pointer to a file structure
int n = 0; // height of array at the beginning (= number of pointers to struct)
int i;
f = fopen("database.txt", "r+");
if (f == NULL)
return 0;
count_songs_db(f, &n); // will modify n (height of array) according to the number of existing songs
printf("n = %d\n", n);
songs = (Song*)malloc(n * sizeof(Song));
load(f, songs, n);
// MENU
free(songs);
fclose(f);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG 50 //just a random value
typedef struct Song
{
char *name;
char *nameSong;
char *timeSong;
int date;
} Song;
void saveToFile(Song *x, int *songCount) //Saves info to the binary file
{
FILE *f = fopen("array.txt", "w");
if (f == NULL)
{
printf("Error\n");
}
fwrite(songCount, sizeof(int), 1, f);
fwrite(x, sizeof(struct Song), (*songCount), f);
fclose(f);
}
void readSong(Song *x, int *songCount) //Reads info fromt he file and writes it
{
FILE *fr = fopen("array.txt", "r");
if (fr == NULL)
{
printf("Error\n");
}
printf("Songs:\n");
fread(songCount, sizeof(int), 1, fr);
fread(x, sizeof(struct Song), (*songCount), fr);
for(int i=0; i < (*songCount); i++)
{
printf("%d. %s %s %s %d\n", (i+1), x[i].name, x[i].nameSong, x[i].timeSong, x[i].date);
}
fclose(fr);
}
void insertSong(Song *x, int Count) //Inserts new song into the array.
{
printf("\nInsert name of the band:\n");
x[Count].name=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].name);
printf("Insert name of the song:\n");
x[Count].nameSong=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].nameSong);
printf("Insert length of the song:\n");
x[Count].timeSong=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].timeSong);
printf("Insert then song was created:\n");
scanf("%d", &(x[Count].date));
printf("\n");
}
main()
{
int songCount, menuOption;
Song *x=malloc(SLENG*sizeof(char)+SLENG*sizeof(char)+SLENG*sizeof(char)+sizeof(int));
printf("1. insert song\n 2. load from file\n ");
scanf("%d", &menuOption);
switch(menuOption)
{
case(1) :
printf("Insert how many songs do you want to input?\n");
scanf("%d", &songCount);
for(int i=0; i<songCount; i++)
{
insertSong(x, i);
}
saveToFile(x, &songCount);
break;
case(2) :
readSong(x, &songCount);
break;
}
}
I have an assingment to write a programm which would input some data into file and could read that data from that file, the problem is probably with fwrite or fread, couse it seems to crash everytime I try to load the and write the data from file. Any ideas why is it not working properly? And can I even do it like this as it is dynamic struct array. Thanks in advance.
In order to save the structure to a file, it must only contain scalar values, not pointers into memory objects. Modify your structure to use arrays instead of pointers:
typedef struct Song {
char name[SLENG];
char nameSong[SLENG];
char timeSong[SLENG];
int date;
} Song;
And modify the code accordingly, but note that:
saving and reading the structures to and from a file requires opening it in binary mode "wb" and "rb".
it is very misleading to name a binary file array.txt.
you do not need to pass the address of the count when writing to the file, but you need to pass the address of the array pointer when reading as you do not know yet how much memory to allocate.
Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG 50 // this value is used in the file format
typedef struct Song {
char name[SLENG];
char nameSong[SLENG];
char timeSong[SLENG];
int date;
} Song;
int saveToFile(Song *x, int songCount) { //Saves info to the binary file
FILE *f = fopen("array.bin", "wb");
if (f == NULL) {
printf("Error\n");
return -1;
}
fwrite(songCount, sizeof(int), 1, f);
int written = fwrite(x, sizeof(struct Song), songCount, f);
fclose(f);
return written;
}
int readSong(Song **x, int *songCount) { //Reads info from the file and writes it
int count = 0;
FILE *fr = fopen("array.bin", "rb");
if (fr == NULL) {
printf("Error\n");
return -1;
}
printf("Songs:\n");
fread(&count, sizeof(int), 1, fr);
*x = calloc(count, sizeof(Song));
if (*x == NULL) {
printf("Cannot allocate %d bytes of memory\n", count);
fclose(fr);
return -1;
}
int found = fread(*x, sizeof(struct Song), count, fr);
for (int i = 0; i < found; i++) {
printf("%d. %s %s %s %d\n", i + 1,
(*x)[i].name, (*x)[i].nameSong, (*x)[i].timeSong, (*x)[i].date);
}
fclose(fr);
return *songCount = found;
}
void insertSong(Song *x, int Count) { //Inserts new song into the array.
printf("\nInsert name of the band:\n");
scanf("%49s", x[Count].name);
printf("Insert name of the song:\n");
scanf("%49s", x[Count].nameSong);
printf("Insert length of the song:\n");
scanf("%49s", x[Count].timeSong);
printf("Insert then song was created:\n");
scanf("%d", &(x[Count].date));
printf("\n");
}
int main(void) {
int songCount, menuOption;
Song *x = NULL;
printf("1. insert song\n 2. load from file\n ");
scanf("%d", &menuOption);
switch (menuOption) {
case 1:
printf("Insert how many songs do you want to input?\n");
if (scanf("%d", &songCount) == 1) {
x = calloc(songCount, sizeof(Song));
for (int i = 0; i < songCount; i++) {
insertSong(x, i);
}
saveToFile(x, songCount);
}
break;
case 2:
readSong(&x, &songCount);
break;
}
free(x);
x = NULL;
return 0;
}
When running this code with an input .txt file containing somewhere between 200-300 integers (separated by spaces) i get an error right before the for loop with the fprintf statement.
I am not sure if qsort is causing this error or why it occurs but any insight would be appreciated.
(this file is run by adding the name of the input file and the output file in the command line ex: ./program input.txt output.txt
My code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main(int argc, char *argv[]){
if(argc != 3){
printf("\nInvalid input\nPlease provide the input and output text file names as %s name1 name2\n", argv[0]);
}else{
printf("\nPart A: \n");
printf("..............................................................................................................\n\n");
char *fn1 = argv[1]; //variables
char *fn2 = argv[2];
int temp = 0;
int counter = 0;
int index = 0;
int index2 = 0;
int sort = 0;
FILE *fp1 = fopen(fn1, "r"); //read file
FILE *fp2 = fopen(fn2, "w"); //write file
if(fp1 == NULL){ //test if fp1 was opened
printf("There was an error opening the input file");
}
char data[10]; //ints can only hold 10 digits
int *integerArr;
int *tempPointer;
integerArr = malloc(10*sizeof(int));
int sizeOfArrs = 10;
printf("Reading in the textfile: ");
while(fscanf(fp1,"%s",data) != EOF){ //reads in the file breaking on each whitespace and ends at the EOF pointer
temp = strlen(data);
if(temp <=10){
temp = atoi(data);
integerArr[counter] = temp;
printf(".");
counter++;
if(counter == sizeOfArrs -1){
temp = sizeOfArrs * 2;
tempPointer = realloc(integerArr, temp);
if(tempPointer != NULL){
integerArr = tempPointer;
}
}
}else printf("\ninteger had too many digits\n");
}
printf(" Done\n%d Numbers were found\n", counter);
printf("The integers found in the %s file: \n", argv[1]);
index = 0; //reset index to 0;
for(index;index<counter;index++){ //prints the unsorted contents of the file
printf("%d ", integerArr[index]);
}
printf("\n\nPart B\n");
printf("..............................................................................................................\n\n");
printf("The integers found in the %s file after sorting: \n", argv[1]);
qsort(integerArr, counter, sizeof(int), cmpfunc); //best function ever (sorts the array using the cmpfunc to tell if an integer is greater than less than or equal to the next one)
index = 0; //resets the index
for(index; index <counter; index++){ //prints the sorted contents of the file
printf("%d ", integerArr[index]);
fprintf(fp2,"%d ",integerArr[index]); //writes the sorted integers to the new file
}
if(fp2 == NULL){ //tests if the write worked
printf("There was an error writing the outputfile");
}
printf("\n");
close(fp1,fp2); //closes both files
}
return 0;
}
Your fscanf loop is broken. You weren't actually realloc'ing with a larger size. Here's the corrected program [sorry for the pedantic style reedit but you hit one of my nits: long sidebar comments]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int
cmpfunc(const void *a, const void *b)
{
return (*(int *) a - *(int *) b);
}
int
main(int argc, char *argv[])
{
if (argc != 3) {
printf("\nInvalid input\nPlease provide the input and output text file names as %s name1 name2\n", argv[0]);
return 1;
}
printf("\nPart A: \n");
printf("..............................................................................................................\n\n");
char *fn1 = argv[1]; // variables
char *fn2 = argv[2];
int temp = 0;
int counter = 0;
int index = 0;
int index2 = 0;
int sort = 0;
FILE *fp1 = fopen(fn1, "r");
FILE *fp2 = fopen(fn2, "w");
// test if fp1 was opened
if (fp1 == NULL) {
printf("There was an error opening the input file");
return 1;
}
// ints can only hold 10 digits
char data[10];
int *integerArr;
int *tempPointer;
int sizeOfArrs = 10;
integerArr = malloc(sizeOfArrs * sizeof(int));
printf("Reading in the textfile: ");
// reads in the file breaking on each whitespace and ends at the EOF
// pointer
while (fscanf(fp1, "%s", data) != EOF) {
temp = strlen(data);
if (temp > 10) {
printf("\ninteger had too many digits\n");
continue;
}
temp = atoi(data);
integerArr[counter] = temp;
printf(".");
counter++;
if (counter == sizeOfArrs - 1) {
sizeOfArrs += 600;
integerArr = realloc(integerArr, sizeOfArrs * sizeof(int));
}
}
// trim array to actual size needed
sizeOfArrs = counter;
integerArr = realloc(integerArr, sizeOfArrs * sizeof(int));
printf(" Done\n%d Numbers were found\n", counter);
printf("The integers found in the %s file: \n", argv[1]);
// prints the unsorted contents of the file
for (index = 0; index < counter; index++) {
printf("%d ", integerArr[index]);
}
printf("\n\nPart B\n");
printf("..............................................................................................................\n\n");
printf("The integers found in the %s file after sorting: \n", argv[1]);
// best function ever (sorts the array using the cmpfunc to tell if an
// integer is greater than less than or equal to the next one)
qsort(integerArr, counter, sizeof(int), cmpfunc);
// prints the sorted contents of the file
for (index = 0; index < counter; index++) {
printf("%d ", integerArr[index]);
// writes the sorted integers to the new file
fprintf(fp2, "%d ", integerArr[index]);
}
// tests if the write worked
if (fp2 == NULL) {
printf("There was an error writing the outputfile");
}
printf("\n");
// closes both files
fclose(fp1);
fclose(fp2);
return 0;
}
Also, note the fclose's at the bottom. There are a few minor bugs left for you to find.