I'm having some trouble with parsing a temp.txt folder which contains the basenames of various files in a directory. I'd like to sort through this file, figure out what each of the file types are line by line, and then delete them from the temp file. I have been able to do carry out the parsing of the file names to discover their type, but when I call my delete function... it only works for some of the files and leaves behind some junk occasionally.
The input file looks like this:
temp.txt input
The output file after running looks like this:
temp.txt output
#include < stdio.h >
#include < string.h >
#include < unistd.h >
#include < stdlib.h >
/* This program module parses through the temp.txt file and finds .gif, .png, and .bmp files
and prints to standard output their file type in the order in which they're found.
It also takes all the files that aren't of those three types and puts them in a junk file.
*/
int deleteline(int delete_line);
int main(int argc, char * argv[]) {
FILE * file = fopen("temp.txt", "r"); /* should check the result */
FILE * myfile = fopen("junkfiles.txt", "w");
char line[4069];
char * gif = ".gif";
char * png = ".png";
char * bmp = ".bmp";
int i = 0;
int j = 0;
// if tempfile cannot be created, error handle
if (!file) {
puts("Some kind of file error!");
return 1;
}
// if junkfile cannot be created, error handle
if (!myfile) {
puts("Some kind of file error!");
return 1;
}
while (fgets(line, sizeof(line), file)) {
i++;
if (strstr(line, gif) != NULL) {
j = deleteline(i);
fflush(NULL);
if (j == 0) {
printf("File on line %d is: ", i);
puts(line);
printf("This is a .gif\n\n");
} else {
printf("Some error on line %d\n", i);
}
} else if (strstr(line, png) != NULL) {
j = deleteline(i);
if (j == 0) {
printf("File on line %d is: ", i);
puts(line);
printf("This is a .png\n\n");
} else {
printf("Some error on line %d\n", i);
}
} else if (strstr(line, bmp) != NULL) {
j = deleteline(i);
if (j == 0) {
printf("File on line %d is: ", i);
puts(line);
printf("This is a .bmp\n\n");
} else {
printf("Some error on line %d\n", i);
}
} else {
j = deleteline(i);
if (j == 0) {
printf("The file on line %d is junk.\n\n", i);
} else {
printf("Some error on line %d\n\n", i);
}
fprintf(myfile, "%s", line);
}
}
/* may check feof here to make a difference between eof and io failure -- network
timeout for instance */
fclose(file);
fclose(myfile);
fflush(NULL);
return 0;
}
int deleteline(int delete_line) {
FILE * fileptr1, * fileptr2;
char * filename = "temp.txt";
char ch;
int temp = 1;
//open file in read mode
fileptr1 = fopen(filename, "r");
ch = getc(fileptr1);
//rewind
rewind(fileptr1);
//open new file in write mode
fileptr2 = fopen("replica.txt", "w");
while (ch != EOF) {
ch = getc(fileptr1);
if (ch == '\n')
temp++;
//except the line to be deleted
if (temp != delete_line) {
//copy all lines in file replica.c
putc(ch, fileptr2);
}
}
fclose(fileptr1);
fclose(fileptr2);
remove(filename);
//rename the file replica.c to original name
rename("replica.txt", filename);
return 0;
}
Related
int main()
{
char ch;
int word_count = 0, in_word = 0;
char file_name[MAX_LEN];
/* Pointer for both the file*/
FILE *fpr, *fpw;
/* Opening file INPUT.txt in “r” mode for reading */
start:
printf("Enter a file name: ");
scanf("%s", file_name);
fpr = fopen(file_name, "r");
/* Ensure INPUT.txt opened successfully*/
if (fpr == NULL)
{
system("cls");
printf("Could not open the file %s\n", file_name);
goto start;
}
while ((ch = fgetc(fpr)) != EOF) {
{
printf("%c",ch);
}
if(ch == ' ' || ch == '\t' || ch == '\0' || ch == '\n') {
if (in_word) {
in_word = 0;
word_count++;
}
} else {
in_word = 1;
}
}
printf("In the file %s:\n", file_name);
printf("Number of words: %d.\n", word_count);
/* Opening file OUTPUT.txt in “w” mode for writing*/
fpw= fopen("OUTPUT.txt", "w");
/* Ensure OUTPUT.txt opened successfully*/
if (fpw == NULL)
{
puts("Output file cannot be opened");
}
/*Read & Write Logic*/
while ((ch = fgetc(fpr)) != EOF)
{
fputc(ch, fpw);
}
/* Closing both the files */
fclose(fpr);
fclose(fpw);
return 0;
}
Why is it not printing in the output.txt file? And how can I also print the words in the output file?
There must be a conflict between the while function before printing the input. Or maybe there is something reading before the output then having conflict with another one, when I remove the while function (count words) it shows the product in the output.
You read from fpr until you reach EOF, then try to read from it again.
You need to rewind the file to the beginning for the second fgetc() loop to produce anything.
I have copied the contents of a file to another file and I am trying to get the line, word, and character count. The code I have right now displays the number of lines and words in the file content. Now I need to display the character count but I am unsure of how to do that. I am guessing a for loop? But I am not sure.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_WORD_LEN 100
#define MAX_LINE_LEN 1000
#define ipsumFile "Lorem ipsum.txt"
#define ipsumCopy "Lorem ipsum_COPY.txt"
int wordCount(FILE *fp);
int charCount(FILE *fp);
int sendContentTo(FILE *fp, FILE *out);
int getWordAt(FILE *fp, int pos, char *word);
int appendToFile(char *fileName, char *newText);
int main(void)
{
FILE *fp, *fp2; //"file pointer"
int ch; //place to store each character as read
//open Lorem ipsum.txt for read
if ((fp = fopen(ipsumFile, "r")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumFile);
exit(EXIT_FAILURE);
}
//open Lorem ipsumCopy for writing
if ((fp2 = fopen(ipsumCopy, "w+")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumCopy);
exit(EXIT_FAILURE);
}
//print out and count all words in Lorem ipsum.txt
int numOfWords = wordCount(fp);
//print out and count all lines in Lorem ipsum.txt
int numOfLines = sendContentTo(fp, stdout);
//copy the content of Lorem ipsum.txt into a new file (ipsumCopy)
numOfLines = sendContentTo(fp, fp2);
fclose(ipsumFile);
fclose(ipsumCopy);
// close Lorem ipsum.txt
if (fclose(fp) != 0)
fprintf(stderr, "Error closing file\n");
if (fclose(fp2) != 0)
fprintf(stderr, "Error closing copy\n");
return 0;
}
int sendContentTo(FILE *in, FILE *out)
{
fprintf(stdout, "Performing file copy...\n\n");
//start at the beginning of the file
rewind(in);
// array to hold one line of text up to 1000 characters
char line[MAX_LINE_LEN];
int lineCount = 0;
// read one line at a time from our input file
while (fgets(line, MAX_LINE_LEN, in) != NULL)
{
//send line we just read to output.
fprintf(out, "%s", line);
//count the lines
lineCount++;
}
fprintf(stdout, "\nFinished line count.\n");
fprintf(stdout, "Count is: %d.\n\n", lineCount);
// Return how many text lines
// we've processed from input file.
return lineCount;
}
// Read content from file one character at a time.
// Returns number of total characters read from the file.
int charCount(FILE *fp)
{
fprintf(stdout, "Performing char count...\n\n");
rewind(fp);
int charCount = 0;
char ch;
//print out each character, and return the
// number of characters in the file.
fprintf(stdout, "\nFinished character count. \n");
fprintf(stdout, "Count is: %d. \n\n", charCount);
return charCount;
}
// Read content from file one word at a time.
// Returns number of total words read from the file.
int wordCount(FILE *fp)
{
fprintf(stdout, "Performing word count...\n\n");
rewind(fp);
char word[MAX_WORD_LEN];
int wordCount = 0;
while (fscanf(fp, "%s", word) == 1)
{
// Send entire word string
// we just read to console
puts(word);
//count the word
wordCount++;
}
fprintf(stdout, "\nFinished word count.\n");
fprintf(stdout, "Count is: %d.\n\n", wordCount);
return wordCount;
}
You don't need to write different function for counting the number of lines, words, and characters in a file. You can do it in a single parsing of file character by character and while parsing, in order to copy the content of file to another file, you can write the characters to another file. You can do:
#include <stdio.h>
#include <stdlib.h>
int count_and_copy(const char * ipsumFile, const char * ipsumCopy)
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0, c;
FILE *fp, *fp2;
if ((fp = fopen(ipsumFile, "r")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumFile);
exit(EXIT_FAILURE);
}
if ((fp2 = fopen(ipsumCopy, "w+")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumCopy);
exit(EXIT_FAILURE);
}
while((c = fgetc(fp)) != EOF)
{
fputc(c, fp2); // write character c to the copy file
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
fclose (fp2);
printf ("Number of lines : %u\n", lCount);
printf ("Number of words : %u\n", wCount);
printf ("Number of characters : %u\n", cCount);
return 0;
}
int main()
{
/* Assuming, you want to count number of lines, words
* and characters of file1 and copy the contents of file1
* to file2.
*/
count_and_copy("file1", "file2");
return 0;
}
I suppose that the following approach will work:
void *cw(const char *fname)
{
FILE *f = fopen(fname, "r");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", fname, strerror(errno));
exit(EXIT_FAILURE);
}
int bc = 0; /* bytes counter */
int wc = 0 ; /* words counter */
int nlc = 0; /* new lines counter */
const int in_word_state = 0;
const int out_word_state = 1;
int state = out_word_state;
int c = 0;
for (;;) {
c = fgetc(f);
if (ferror(f) != 0) {
perror("fgetc");
goto error;
}
if (feof(f))
break;
if (c == '\n')
nlc++;
if (c == ' ' || c == '\t' || c == '\n')
state = out_word_state;
if (state == out_word_state) {
state = in_word_state;
wc++;
}
bc++;
}
if (fclose(f) == EOF) {
perror("fclose");
goto error;
}
printf("w: %d, c: %d, l:%d\n", wc, bc, nlc);
error:
if (f != NULL) {
if (fclose(f) == EOF) {
perror("fclose");
}
}
exit(EXIT_FAILURE);
}
One of my assignments has the following question:
One function (function #2) of your program is to read in the content of an instance file. To read in
the file "
instance10
001.txt
" you will execute the command:
NameOfProgram -i instance10
001.txt
Here "
-i " is the command-line option that indicates the succeeding argument is the
input filename.
This is what I have done so far, mostly a skeleton:
/* Assignment 1 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
FILE *fp;
int max_x, max_y, num_pt, rand_inst;
int *x_coordinate, *y_coordinate;
int inputfile = 0, outputfile = 0;
int i;
if (argc == 1)
{
/* to generate random instances, accepting parameters from stdin */
printf("Generating random instances...");
printf("Enter the circuit board size MAX_X MAX_Y: ");
scanf("%d %d", &max_x, &max_y);
printf("Enter the number of points NUM_PT: ");
scanf("%d", &num_pt);
printf("Enter the number of random instances to be generated: ");
scanf("%d", &rand_inst);
return 1;
}
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "-i") == 0)
inputfile = i+1;
else if (strcmp (argv[i], "-o") == 0)
outputfile = i+1;
}
if (inputfile == 0)
{
/* invalid comman line options */
printf("\nIncorrect command-line\n");
printf("myprogram [-i inputfile [-o outputfile]]");
return -1;
}
**/* THIS IS WHERE I NEED HELP */**
if (inputfile == 1)
{
fp = fopen(/*Name of the input file (instance10_001.txt) */, "r")
}
if ((fp = fopen(argv[inputfile], "r")) == NULL)
{
/* open file error */
return -2;
}
while (fscanf(fp, "%d", &max_x) != 1)
{
if (ferror(fp))
{
/* read error */
fclose(fp);
return -3;
}
if (feof(fp))
{
/* no integer to read */
fclose(fp);
return -4;
}
fscanf(, "%*[^\n]"); /*skip the rest of line */
}
if (fscanf(fp, "%d", &max_y) != 1)
{
/* max_y not following max_x */
fclose(fp);
return -5;
}
while (fscanf(fp, "%d", &num_pt) != 1)
{
if(ferror(fp))
{
/* read error */
fclose(fp);
return -6;
}
if (feof(fp))
{
/* no integer to read */
fclose(fp);
return -7;
}
fscanf(fp, "%*[^\n]"); /* skip the rest of line */
}
x_coordinate = (int *)malloc(num_pt * sizeof(int));
y_coordinate = (int *)malloc(num_pt * sizeof(int));
for (i = 0; i < num_pt; i++)
{
while (fscanf(fp, "%d", &x_coordinate[i]) != 1)
{
if (ferror(fp))
{
/* read error */
fclose(fp);
return -8;
}
if (feof(fp))
{
/* no integer to read */
fclose(fp);
return -9;
}
fscanf(fp, "%*[^\n]"); /* skip the rest of line */
}
if (fscanf(fp, "%d", &y_coordinate[i]) != 1)
{
/* y_coordinate not following x_coordinate */
fclose(fp);
return -10;
}
}
fclose(fp);
if (outputfile > 0)
{
if ((fp = fopen(argv[outputfile], "w")) == NULL)
{
/* open file error */
return -2;
}
fprintf(fp, "##################################################\n");
fprintf(fp, "#%s\n", argv[inputfile]);
fprintf(fp, "#area [0, MAX_X] x [0, MAX_Y]\n");
fprintf(fp, "%d\t%d\n", max_x, max_y);
fprintf(fp, "#number of points NUM_PT\n");
fprintf(fp, "%d\n", num_pt);
fprintf(fp, "#coordinates\n");
for (i = 0; i < num_pt; i++)
{
fprintf(fp, "%d\t%d\n", x_coordinate[i], y_coordinate[i]);
}
fprintf(fp, "#end of instance\n");
fclose(fp);
}
else
{
printf("##################################################\n");
printf("#%s\n", argv[inputfile]);
printf("#area [0, MAX_X] x [0, MAX_Y]\n");
printf("%d\t%d\n", max_x, max_y);
printf("#number of points NUM_PT\n");
printf("%d\n", num_pt);
printf("#coordinates\n");
for (i = 0; i < num_pt; i++)
{
printf("%d\t%d\n", x_coordinate[i], y_coordinate[i]);
}
printf("#end of instance\n");
}
free(x_coordinate);
free(y_coordinate);
return 0;
}
I am wondering how I can read the name of the input file from bash terminal. Should I use scanf?
how do I get what the user has inputted as the input file? Like for example if the user is running my program from bash with ./myprogram -i instance10_001.txt, how can I open the inputted file in my program?
PS I am using my Ubuntu terminal to access my lab computer via ssh.
Language: c99 ; Compiler: gcc
This looks like a simple error in your if statment. You're saying if, and only if, inputfile is 1 (which means -o must have been argv[0]) it will open inputfile.
if (inputfile == 0)
{
/* invalid command line options */
printf("\nIncorrect command-line\n");
printf("myprogram [-i inputfile [-o outputfile]]");
return -1;
}
else /* if inputfile is not equal to 0, then this will execute. */
{
fp = fopen(argv[inputfile], "r");
}
Also, there's another problem here, in which you assign fp to a function and then reopen the file already opened in fp:
/* removed fp = fopen (a function) */
if (fp == NULL) /* You already opened the file; no need to open again until fclose */
{
/* open file error */
return -2;
}
Also, in this block of code:
while (fscanf(fp, "%d", &x_coordinate[i]) != 1)
{
if (ferror(fp))
{
/* read error */
fclose(fp);
return -8;
}
if (feof(fp))
{
/* no integer to read */
fclose(fp);
return -9;
}
fscanf(fp, "%*[^\n]"); /* skip the rest of line */
}
Fscanf returns the number of arguments successfully filled, which in this case, will always be 1.
Note that similar problems may be present in the remainder of the code.
I want to write my own code for tail Unix command but I am having a lot of trouble doing that. I am completely new to C language and apparently lost on how to fix my code. I am having number of problems regarding my code:
I am unable to read and print lines from text file in the if statements it is not printing any string from file when I run it don't know why?
Unable to print specific lines in if statement by taking user input as starting line and then printing till the End of File.
I am having trouble figuring out the right solution to my problems and debugging what problems there are in code.
I would really appreciate your help in figuring how to do all the above in my code. If someone can help make changes and get my code to work right.
#include <stdio.h>// for fopen, fscanf, fclose, fprintf
#include <stdlib.h>// for exit
#include <string.h>
int main(int argc, const char * argv[]){
printf("Opening file\n");
char filename[64]; // file attribute
strcpy(filename, argv[1]); //copy string from argv[1] to filename
printf("FILENAME: %s \n", filename);
FILE* fp; // file pointer
int ch, linestotal = 0, user;
char c[10000];
if(argv[2]){ //checking input argv[2]
user = atoi(argv[2]); // char to int
}
fp = fopen( filename, "r"); // file read
if(fp == NULL){ // verify file is opened
printf("Error opening file");
exit(1);
}
while(!feof(fp)) // check end of file
{
ch = fgetc(fp);
if(ch == '\n')
{
linestotal++; //Checking total lines inside file
}
}
printf("Total no. of lines: %d\n", linestotal );
printf("User input: %d\n", user );
printf("**********************\n");
if (!user && linestotal<= 10)
{
while ( (ch = fgetc(fp) ) != EOF)
printf("%c", ch);
fclose(fp);
printf("********************\n");
}if(!user && linestotal>10) { // to print 10 lines
for(int i = (linestotal-10); i <= (linestotal); i++)
{ c[i] = fgetc(fp);
printf("%c", c[i]);
}
fclose(fp);
printf("********************\n");
}if(user && user<linestotal) {
for(int i = (linestotal-user); i <= (linestotal); i++)
{ c[i] = fgetc(fp);
printf("%c", c[i]);
}
fclose(fp);
printf("********************\n");
}if(user && user>linestotal){
while ( (ch = fgetc(fp) ) != EOF)
printf("%c", ch);
fclose(fp);
printf("********************\n");
}else{
printf("Unable to read and print file \n");
}
printf("End of file");
return 0;
}
This code opens a directory, and for every file in the directory it loops through every line of data inside the file, and then parses it to do some calculations and outputs the resulting data into a new file.
The problem is that I can only output a maximum of around 1021 files. I'm closing all of the fopens after outputting all the data, so I'm not sure what I'm doing wrong.
Shouldn't fclose() be closing the open files therefore this not happening?
int main(int argc, char *argv[])
{
//sample data values
double lat;
double lon;
double convergence;
double pt_scale;
int zone = 54;
double major_axis = 6378137.0000;
double flattening = (1/298.2572);
double zoneWidth = 6;
double centMeridian = -177;
double falseEast = FALSE_EASTING;
double falseNorth = FALSE_NORTHING;
double scale = SCALE_FACTOR;
int max_size = 128;
int current_size = max_size;
char *pathStr = malloc(max_size);
char *outPathStr = malloc(max_size);
char coData[100]; //max length of line;
long firstTerm, secondTerm; //terms we will split the line into, lat, lon, elevation.
int counter = 0; //pos counter
int d = EOF; //end of file ASCII
char strIn[200];
char* elevation;
char strOut[200];
char dirOut[200]; //sprintf must use a actual defined buffer otherwise there will be a buffer overflow.
char* cchr;
int j;
_setmaxstdio(2048);
printf("Please enter the path of the files: \n");
getUserInput(pathStr, current_size, max_size);
printf("Please enter the output path of the files: \n");
getUserInput(outPathStr, current_size, max_size);
//loop through each file in the directory. Open the file, convert, then close it.
//we will use dirent.h as it is cross platform so we wont have to worry about sharing issues
DIR *dir; //new directory
struct dirent *ent;
dir = opendir(pathStr); //allcate it a path
if(opendir(pathStr) == NULL)
{ printf("Error: %d (%s)\n", errno, strerror(errno));}
int k;
if(dir != NULL)
{
while((ent = readdir(dir)) != NULL) //loop through each file in the directory.
{
//open the file and loop through each line converting it then outputing it into a new file
if((!strcmp(ent->d_name,"..") || !strcmp(ent->d_name,".")) == 1)
{
//dont want these directories
continue;
}
else
{
sprintf(strIn,"%s%s",pathStr,ent->d_name); //get the file n
FILE *fp = fopen(strIn, "r");
if(fopen(strIn, "r") == NULL) //for inputting file
{ printf("Error: %d (%s)\n", errno, strerror(errno));
getchar();
break; }
sprintf(dirOut,"%s%d%s",outPathStr,counter,".geo");
printf("%s \n",dirOut);
FILE *fp2 = fopen(dirOut, "w"); //for outputting file
if(fopen(dirOut, "w") == NULL)
{ printf("Error: %d (%s)\n", errno, strerror(errno));
getchar();
break; }
while(fgets(coData, 100, fp) != NULL)//loop through line by line, allocate into 2 doubles and a string, pass the two coordinates and convert
{
//extract terms from coData
char * pch; //pointer to array pos
char * pend;
pch = strtok(coData," ");
j = 0;
while(j <= 2) //We only want to split the first three parameters.
{
//convert char array to double for co-oridinate conversion
if(j == 0)
{
firstTerm = atof(pch); //latitude;
j++;
continue;
}
if(j == 1)
{
pch = strtok(NULL, " ");
secondTerm = atof(pch); //longitude
j++;
continue;
}
if(j == 2)
{
pch = strtok(NULL," ");
elevation = pch; //elevation doesnt need to be converted because it isnt used in the coordinate conversion.
break;
}
}
grid2spheroid(&lat,&lon,&convergence,&pt_scale,firstTerm,secondTerm,zone,0, major_axis,flattening,zoneWidth,centMeridian,falseEast,falseNorth,scale);
sprintf(strOut,"%f %f %s",lat,lon,elevation);
//printf("%d %d", lat, lon);
fputs(strOut,fp2);
} //end of while
fclose(fp2);
fclose(fp);
counter++;
}
}
closedir(dir);
}
free(pathStr); //finished using the path string so we can finish the
free(outPathStr);
getchar();
return 0;
}
void getUserInput(char *pathStr, int current_size, int max_size)
{
unsigned int i = 0;
if(pathStr != NULL)
{
int c = EOF;
//get the user input and reallocate the memory size if the input it too large.
while((c = getchar()) != '\n' && c != EOF) //WHILE NOT END OF FILE OR NEW LINE (USER PRESSED ENTER)
{
pathStr[i++] = (char)c;
if(i == current_size)
{
current_size = i+max_size;
pathStr = realloc(pathStr, current_size);
}
}
}
}
You aren't closing all the files ;-)
FILE *fp = fopen(strIn, "r");
if(fopen(strIn, "r") == NULL) //for inputting file
Same applies to your output.
I think you meant something more like:
FILE *fp = fopen(strIn, "r");
if(fp == NULL) //for inputting file
{
// error handling.
No, no! You're opening every file twice (and only closing once)!
/* Bad! */
dir = opendir(pathStr); //allcate it a path
if(opendir(pathStr) == NULL)
{ printf("Error: %d (%s)\n", errno, strerror(errno));}
int k;
/* Correct */
dir = opendir(pathStr); //allocate it a path
if(!dir) {
printf("Error: %d (%s)\n", errno, strerror(errno));
return;
}
You're also doing the same thing with fopen(). In both places :)
Just check the pointer; don't call "fopen()" a second time; don't call "opendir()" a second time!
Also: please don't put code on the same line as your opening brace. OK?
dir = opendir(pathStr); //allcate it a path
if(opendir(pathStr) == NULL)
(...)
FILE *fp2 = fopen(dirOut, "w"); //for outputting file
if(fopen(dirOut, "w") == NULL)
(...)
FILE *fp = fopen(strIn, "r");
if(fopen(strIn, "r") == NULL) //for inputting file
Here you open the file twice but only store the pointer once. Change these to:
FILE *fp = fopen(strIn, "r");
if(fp == NULL) //for inputting file
and the other one in the same way.