C program to merge files not finding EOF, stuck in infinite loop! - c

I'm having some problems trying to run this program I am working on...The requirements say I was not allowed to use a sort function...I had do something myself....etc.
Pretty much, the program compiles but hangs after executed...I'm guessing it's stuck in an infinite loop...but I can't seem to find it... :(
This program reads to data files that will already be ordered least to greatest and merges them (ordered) into a third .txt file...
The two files are Data1.txt and Data2.txt
contains:
Data1.txt
2
2
2
2
Data2.txt
1
3
5
7
9
combine.c
#include <stdio.h>
#include <stdlib.h>
void sortData(FILE *fpData1, FILE *fpData2)
{
int n, m;
FILE *fpMerge;
fpMerge = fopen("Merge.txt", "w+");
fscanf(fpData2, "%i", &n);
fscanf(fpData1, "%i", &m);
while(n != EOF || m != EOF)
{
if(n == EOF)
{
fscanf(fpData1, "%i", &m);
while(m != EOF)
{
fprintf(fpMerge, "%i\n", m);
fscanf(fpData1, "%i", &m);
}
}
if(m == EOF)
{
fscanf(fpData2, "%i", &n);
while(n != EOF)
{
fprintf(fpMerge, "%i\n", n);
fscanf(fpData2, "%i", &n);
}
}
if(n < m)
{
fprintf(fpMerge, "%i\n", n);
fscanf(fpData2, "%i", &n);
}
if(n > m)
{
fprintf(fpMerge, "%i\n", m);
fscanf(fpData1, "%i", &m);
}
if(n == m)
{
fprintf(fpMerge, "%i\n", n);
fprintf(fpMerge, "%i\n", m);
fscanf(fpData2, "%i", &n);
fscanf(fpData1, "%i", &m);
}
}
fclose(fpMerge);
}
int main (void)
{
FILE *fpData1;
FILE *fpData2;
fpData1 = fopen("Data1.txt", "r");
if(fpData1 == NULL)
{
printf("There was an error opening the file...program terminating..\n");
exit(1);
}
fpData2 = fopen("Data2.txt", "r");
if(fpData2 == NULL)
{
printf("There was an error opening the file...program terminating..\n");
exit(1);
}
sortData(fpData1, fpData2);
fclose(fpData1);
fclose(fpData2);
return 0;
}

You don't want to compare n != EOF, but rather the return value of fscanf:
int count_1;
count_1 = fscanf(fpData1, "%i", &m);
if (count_1 == EOF) // EOF (or error)
{
// ...
}
fscanf will also return EOF on error. If you need to tell EOF and error conditions apart, use ferror(fpData1), say, and then look up the error code (stored in errno).

Your testing of EOF is not quite correct
void sortData(FILE *fpData1, FILE *fpData2)
{
int data1;
int data2;
FILE *fpMerge;
fpMerge = fopen("Merge.txt", "w+");
fscanf(fpData1, "%i", &data1);
fscanf(fpData2, "%i", &data2);
// While one file still has data
while(!feof(fpData1) && !feof(fpData2))
{
// Choose 1 file to test
// Read from that file and put into merge file until either we
// run out of data or the condition fails.
if(data1 < data2)
{
do {fprintf(fpMerge, "%i\n", data1);}
while ((fscanf(fpData1, "%i", &data1) != 0) && (data1 <= data2));
}
else
{
do {fprintf(fpMerge, "%i\n", data2);}
while ((fscanf(fpData2, "%i", &data2) != 0) && (data2 <= data1));
}
// NOTE: if fscanf() returns 0 it has failed to read (EOF)
}
// One of the files has reached the EOF
// Dump the other file.
while(fscanf(fpData1, "%i", &data1) != 0) {fprintf(fpMerge, "%i\n", data1);}
while(fscanf(fpData2, "%i", &data2) != 0) {fprintf(fpMerge, "%i\n", data2);}
}

EOF is not a character.
EOF is not an integer.
No files will ever have EOF (neither char nor int) in them.
EOF is a condition.
Files will either be on that condition or (usually) not.
You should check the return value of fscanf() to detect EOF or other problems.

Related

C: printf and scanf statement skipped in this case

i want to make 2 lines calculator program but after first printf,scanf it skipped the second statement
#include <stdio.h>
int main ()
{
int a,b,c,d,abcd;
int e,f,g,h,efgh;
printf("1. ");
scanf("(%d+%d)x(%d-%d)",&a,&b,&c,&d);
printf("2. ");
scanf("(%d+%d)x(%d-%d)",&e,&f,&g,&h);
abcd=(a+b)*(c-d);
efgh=(e+f)*(g-h);
printf("%d %d %d",abcd,efgh);
return 0;
}
and i want to make the program like this:
input
1. (1+2)x(3-4)
2. (5+6)x(7-8)
output
-3 -11
I would strongly suggest you read a line of input using fgets, then use sscanf to parse out the info you need. You will also want to check the return value of sscanf to ensure all four values were read. In this case I have made successful input required to break out of an infinite loop (for (;;) { ... }).
Please note also that all variables do not need to de declared at the start of a function. Instead they can be declared and initialized at their point of use. In this scenario, I have declared abcd and efgh later in main.
#include <stdio.h>
#define LINE_LEN 256
int main ()
{
int a, b, c, d;
int e, f, g, h;
char line[LINE_LEN] = {0};
for (;;) {
printf("1. ");
fgets(line, LINE_LEN, stdin);
if (sscanf(line, "(%d+%d)x(%d-%d)", &a, &b, &c, &d) == 4)
break;
fprintf(stderr, "Bad input. Try again.");
}
for (;;) {
printf("1. ");
fgets(line, LINE_LEN, stdin);
if (sscanf(line, "(%d+%d)x(%d-%d)", &e, &f, &g, &h) == 4)
break;
fprintf(stderr, "Bad input. Try again.");
}
int abcd = (a + b) * (c - d);
int efgh = (e + f) * (g - h);
printf("%d\n", abcd);
printf("%d\n", efgh);
return 0;
}
By some suggestions here I copied the function to read from the stdin in C and adapted your example. This is a safe way to handle stdin from a C application.
Also I tried your code and I believe that what was wrong is that some newline gets "trapped" in the stdin, hence the second scanf returns before you can write anything. That's why this solution.
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
int main ()
{
int a,b,c,d,abcd;
int e,f,g,h,efgh;
int rc;
char buff[20];
rc = getLine ("1. ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}
sscanf(buff, "(%d+%d)x(%d-%d)",&a,&b,&c,&d);
rc = getLine ("2. ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}
sscanf(buff, "(%d+%d)x(%d-%d)",&e,&f,&g,&h);
printf("Check \n");
printf("%d %d %d %d\n" ,a,b,c,d);
printf("%d %d %d %d\n" ,e,f,g,h);
abcd=(a+b)*(c-d);
efgh=(e+f)*(g-h);
printf("Results: %d %d \n",abcd,efgh);
return 0;
}
scanf is wrong..
scanf("%typeOfFirstVariable %typeOfSecondVariable...", &firstVariable, &secondVariable...);
int a,b,c,d,abcd;
int e,f,g,h,efgh;
printf("1. ");
scanf("%d %d %d %d)",&a,&b,&c,&d);
...
return 0;

Not Getting Output in File

#include <stdio.h>
int main()
{
FILE *f1;
int ch, i, n = 0;
char q[500], opt[4][100];
int corAns;
f1 = fopen("C://Users//Lenovo//Desktop//fileInC1.txt", "a+");
if (f1 == NULL)
{
printf("Error Opening File.");
return 0;
}
else
{
while (n != 2)
{
n++;
printf("\nQuestion: ");
fgets(q, 500, stdin);
for (i = 0; i < 4; i++)
{
printf("\nOption %d: ", i + 1);
fgets(opt[i], 100, stdin);
}
printf("\nCorrect answer: ");
scanf("%d", corAns);
//program terminating here after only one iteration
fprintf(f1, "{\nQ: \"%s\", \n\topt: [\"%s\", \"%s\", \"%s\", \"%s\"], \n\tCA: %d }", q, opt[0], opt[1], opt[2], opt[3], corAns);
printf("\nData Written Successfully.");
}
}
fclose(f1);
return 0;
}
I have been trying to create a Javascript generator as you can see in the code.
The main problem i am getting is inside the while loop.
The while loop is terminating after only one iteration and the program not writting the data in the created file. The file already exists.
I am not getting where is the problem occuring.
You need to cleanse your input of new-lines. You also had a redundant Else statement, and Scanf requires the address of a variable, not it's value.
This should work for you. You can check out this question here: Fgets skipping inputs, which I shamelessly copied.
#include <stdio.h>
#include <string.h>
int main()
{
FILE *f1;
int ch, i, n = 0;
char q[500], opt[4][100];
int corAns;
int c;
char *p;
f1 = fopen("fileInC1.txt", "a+");
if (f1 == NULL)
{
printf("Error Opening File.");
return 0;
}
while (n != 2)
{
n++;
printf("\nQuestion: ");
fgets(q, 500, stdin);
if ((p=strchr(q, '\n')) != NULL) *p = '\0';
for (i = 0; i < 4; i++)
{
printf("\nOption %d: ", i + 1);
fgets(opt[i], 100, stdin);
if ((p=strchr(opt[i], '\n')) != NULL) *p = '\0';
}
printf("\nCorrect answer: ");
scanf("%d", &corAns);
//program terminating here after only one iteration
fprintf(f1, "{\nQ: \"%s\", \n\topt: [\"%s\", \"%s\", \"%s\", \"%s\"], \n\tCA: %d }", q, opt[0], opt[1], opt[2], opt[3], corAns);
printf("\nData Written Successfully.");
while ( (c = getchar()) != '\n' && c != EOF );
}
fclose(f1);
return 0;
}

How to use EOF to read all data from file

I'm learning about file i/o in C language and I wrote this program that reads a file, and then for every even number found, it has to print * to the screen.
My problem is that my program keeps printing * forever.
I have tried different ways,some from this website, but I can't seem to understand how to read until end of a text file using EOF.
I want to learn how to read a text file until the end of the file please.
How do I read until the end of a text file? EOF in C.
int main(void)
{
int num;
FILE *ifp;
ifp = fopen("numbers.txt", "r" );
if(ifp == NULL)
{
exit(1);
}
do
{
fscanf(ifp, "%d", &num);
if(num%2 == 0)
{
printf("*\n");
}
} while(num != EOF);
fclose(ifp);
return 0;
}
you need to check the result of the scanf
do
{
int result;
result = fscanf(ifp, "%d", &num);
if(result == EOF) break;
if(result != 1)
{
printf("scanf error\n");
break;
}
if(num%2 == 0)
{
printf("*\n");
}
} while(1);
Instead, you should try while loop.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int num;
FILE *ifp;
ifp = fopen("numbers.txt", "r" );
if(ifp == NULL)
{
perror("Read");
exit(1);
}
while(fscanf(ifp, "%d ", &num) != EOF)
{
if(num % 2 != 0) // For every odd number.
{
printf("*\n");
}
}
fclose(ifp);
return 0;
}
Have you tried this:
while (!feof(ifp)) {
if (fscanf(ifp, "%d ", &num) > 0) {
if(num % 2 != 0) // For every odd number.
{
printf("*\n");
}
}
}
It's doing this because while(num != EOF) is testing whether int num, the number read from the file, is EOF, rather than whether the end of file has been reached.
To test whether the EOF flag has been set on FILE *ifp, use while(!feof(ifp)) instead.

Trouble with C program that reads a MIPS instructions, outputs file with line number, and summary

The problem: Use a c program to read a MIPS instruction file, output it to a second file (both are command line arguments) which contains the contents of the MIPS file, with line numbers. The second half is supposed to display a cross reference table, which details the identifier, the definition(a number), and the usage of that identifier, by line number, for any identifier used more than once.
Unfortunately, I've run aground, and the program not only doesnt seem to actually print anything, but it doesnt seem to make any files either. This is a bit of a last ditch effort, to see if anyone else can help me out.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*Func line takes in a file, and places a line number at the beginning of every
non blank line */
void line(FILE *input, FILE *output) {
char a, c;
int lineNum = 0;
int startOfLine = 1;
char ch;
fprintf(output, "%d ", ++lineNum);
//copy the contents of the input file into the output file
do {
a = fgetc(input);
fputc(a, output);
c = getc(input);
if(a == '\n' && c != '\n') {
if(lineNum > 9)
fprintf(output, "%d ", ++lineNum);
else
fprintf(output, "%d ", ++lineNum);
}
ungetc(c, input);
} while (a != EOF);
printf("ran line: \n");
}
/* Func cross takes in a file, and finds each identifier, marks its definition, and every
use and returns that in the output file */
void cross(FILE *input, FILE *output) {
FILE *temp = fopen("temp.txt", "a+");
int lineNum = 0;
int startOfLine = 1;
char identifier[20][10];
char a, c, i;
int j, k, p;
int size=0;
int def[20];
int use[20][50];
char tempstr[80];
fprintf(output, "Identifier\tDefinition\t Use\n");
fprintf(temp, "%d ", ++lineNum);
//copy contents of input into a temp file
do {
a = fgetc(input);
fputc(a, temp);
c = getc(input);
if(a == '\n' && c != '\n') {
if(lineNum > 9)
fprintf(temp, "%d ", ++lineNum);
else
fprintf(temp, "%d ", ++lineNum);
}
ungetc(c, input);
} while (a != EOF);
fclose(temp);
fopen("temp.txt", "r");
j=0;
//checks to see if current line has an Identifier and if so saves it to an array
//along with the line number it was defined on
while(fgets(tempstr, 80, temp)) {
if(isalpha(tempstr[4]) || tempstr[4] == '_') {
sscanf(tempstr, "%d %[0-9_A-Z_a-z_]", &def[j], identifier[j]);
j++;
size++;
}
}
fclose(temp);
fopen("temp.txt", "r");
//checks for each identifier, on every line whether or not that identifier is used
while(fgets(tempstr, 80, temp)) {
char *tempNum;
sscanf(tempstr, "%s", tempNum);
int tempN = atoi(tempNum);
int n;
p=0;
for(n=0; n<size; n++) {
if(strstr(tempstr, identifier[n]) && tempN > def[n] && tempstr[4] != '#') {
use[n][p] = tempN;
p++;
}
}
}
//writes the identifier, definition, and uses to the file
for(k=0;k<size;k++) {
fprintf(output, "%s\t\t %d\t\t ", identifier[k], def[k]);
for(p=0; p<50; p++) {
if(use[k][p] != NULL && use[k][p] < lineNum && use[k][p] > def[k])
fprintf(output,"%d ", use[k][p]);
}
fprintf(output, "\n");
}
printf("ran cross: \n");
}
/*Func both returns the file with numbered lines and a cross reference table at the bottom of the file */
void both(FILE *input, FILE *output, char *outputName) {
FILE *lineFile = fopen("line.txt", "a+");
FILE *crossFile = fopen("cross.txt", "a+");
char ch;
line(input, lineFile);
cross(input, crossFile);
while( (ch = fgetc(lineFile)) != EOF)
fputc(ch, output);
fprintf(output, "\n\t\t\tCross Reference Table\n");
while( (ch = fgetc(crossFile)) != EOF)
fputc(ch, output);
fclose(output);
printf("ran both: \n");
}
int main(int argc, char * argv[]) {
FILE *input, *output;
output = fopen(argv[4], "a+");
char outputName[50];
strcpy(outputName, argv[4]);
//Error testing
if(argc > 5)
exit(1);
if(strcmp(argv[2], "-l") != 0 && strcmp(argv[2], "-c") != 0 && strcmp(argv[2], "-b") != 0) {
printf("Incorrect flag syntax... Exiting\n");
exit(1);
}
if((input = fopen(argv[3], "r+")) == NULL) {
printf("Input file could not be opened... Exiting\n");
exit(1);
}
else {
if(strcmp(argv[2], "-l") == 0) {
line(input, output);
}
else if(strcmp(argv[2], "-c") == 0)
cross(input, output);
else {
both(input, output, outputName);
}
}
printf("ran main: \n");
return 0;
}

fopen() in concurrent programming

char aux[20];
char aux1[20];
int c;
FILE* archAuxE;
FILE* archAuxS;
sprintf(aux, "%d.txt" ,getpid() );
archAuxS = fopen( aux, "a");
if (archAuxS == NULL) {
printf("this is NOT being printed\n");
}
for (j=0; j<nHijos; j++) {
waitpid(hijosH[0], &estado, 1);
sprintf(aux1, "%d.txt", hijosH[0]);
printf("%s---- entrada\n", aux1);
archAuxE = fopen( aux1, "r");
if (archAuxE == NULL) {
printf("This is being printed :( \n");
}
while ( (c = fgetc(archAuxE)) != EOF ) {
printf("%c ", c);
if (c != '\n') {
fprintf(archAuxS, "%c", c);
}
}
}
Hi, this is my code, its a father that waits for its children and concatenates their results using files named after their pid, but I dont know why the archAuxE fopen is returning NULL because I have all those files created. at that time. is that a problem with sprintf or simple a problem of bad handling of the concurrence?.

Resources