Read a line from text file and delete it - c

I want to read a text file line by line, perform some checks, and if the line is not required, delete it.
I have done the code for reading line, but I don't know how to delete that line if it is not required by me.
Please help me find the simplest method for deleting the line.
Here is my code snippet what I tried:
char ip[32];
int port;
DWORD dwWritten;
FILE *fpOriginal, *fpOutput;
HANDLE hFile,tempFile;
hFile=CreateFile("Hell.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
tempFile=CreateFile("temp.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
WriteFile(hFile,"10.0.1.25 524192\r\n\r\n10.0.1.25 524193\r\n\r\n",strlen("10.0.1.25 524192\r\n\r\n10.0.1.25 524193\r\n\r\n"),&dwWritten,0);
fpOriginal = fopen("Hell.txt", "r+");
fpOutput = fopen("temp.txt", "w+");
while (fscanf(fpOriginal, " %s %d", ip, &port) > 0)
{
printf("\nLine1:");
printf("ip: %s, port: %d", ip, port);
char portbuff[32], space[]=" ";
sprintf(portbuff, "%i",port);
strcat(ip," ");
strcat(ip,portbuff);
if(port == 524192)
printf("\n Delete this Line now");
else
WriteFile(tempFile,ip,strlen(ip),&dwWritten,0);
}
fclose(fpOriginal);
fclose(fpOutput);
CloseHandle(hFile);
CloseHandle(tempFile);
remove("Hell.txt");
if(!(rename("temp.txt","Bye.txt")))
{
printf("\ncould not rename\n");
}
else
printf("\nRename Done\n");
//remove ("Hell.txt");

here's an example:
char* inFileName = "test.txt";
char* outFileName = "tmp.txt";
FILE* inFile = fopen(inFileName, "r");
FILE* outFile = fopen(outFileName, "w+");
char line [1024]; // maybe you have to user better value here
int lineCount = 0;
if( inFile == NULL )
{
printf("Open Error");
}
while( fgets(line, sizeof(line), inFile) != NULL )
{
if( ( lineCount % 2 ) != 0 )
{
fprintf(outFile, "%s", line);
}
lineCount++;
}
fclose(inFile);
fclose(outFile);
// possible you have to remove old file here before
if( !rename(inFileName, outFileName) )
{
printf("Rename Error");
}

You can copy all line wich does not contain the number 2 into a new file and then use the new file instead the old file
fp = fopen("File.txt", "r");
fp2 = fopen("File_copy.txt", "w");
while (fscanf(fp, " %s %d", string, &number) > 0) {
if(number != 2)
{
fprintf(fp2, "%s %d\n", string, number);
}
}
close(fp);
close(fp2);
remove("File.txt");
rename( "File_copy.txt", "File.txt" );

Another solution could be to write back to the same file (write back what you read out except for the lines you don't want) and use the Windows API function SetEndOfFile to truncate it when finished. This will probably be a bit messier to code but you won't need to create a second copy of the file so it's more efficient from a disk usage standpoint.

There are many to solve this problem one of them is, you can open another file for writing when you reach at a point where you don't want to write omit that paint and continue writing until end of file. Latterly you can delete old file and rename new file with old one.
if(number == 2)
{
continue;
}
else
{
writetofilefunction()
}

Related

Check duplicates words in a file

I want to check if there are any duplicates in a .txt file. I've wrote a code but it's not running. I'm not sure about opening the norep.txt file in "a+" mode. The idea is to put the first word of my text in the norep.txt file, then compare every word in the text.txt with the words in norep.txt and copy only the words I need in the file.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fd;
FILE *ft;
char aux[30];
char aux1[30];
int len;
fd = fopen("c:\\text.txt", "r");
if (fd == NULL) {
puts("Error");
}
ft = fopen("c:\\norep.txt", "a+");
if (ft == NULL) {
puts("Error");
}
fscanf(fd, "%s", aux);
fprintf(ft, "%s", aux);
rewind(fd);
rewind(ft);
while (!feof(fd)) {
fscanf(fd, "%s", aux);
while (!feof(ft)) {
fscanf(ft, "%s", aux1);
len = strcmp(aux, aux1);
if (len != 0) {
fprintf(ft, "%s", aux);
}
}
rewind(ft);
}
return 0;
}
You should flush the output file before you rewind it.
fflush - flush a stream or fflush
Of course, this will not fix your problem because:
Note below that the manual says that reposition operations are ignored so that your attempt to read will always find the end of file.
append: Open file for output at the end of a file. Output operations
always write data at the end of the file, expanding it. Repositioning
operations (fseek, fsetpos, rewind) are ignored. The file is created
if it does not exist.
What you should probably do is create an internal memory table that keeps all the unique entries and write it out to a new file after all processing is done. As you read the fd file, check the list and add a new entry if it is not already in the list. Then after you have finished processing fd, then and only then write out your list. Of course, this may be too big depending on the size of your data file.
You could append each unique entry to the output file as you go. but you would need to have some method of checking the previous entries without trying to read the output file.
The usual way to go about this is to read the input file word for word, store the necessary information in some way and then, after you have read all information from the file, write the desired output to the output file.
A rough skeleton of that approach might look like this:
int main()
{
const char *infile = "text.txt";
const char *outfile = "norep.txt";
FILE *in;
FILE *out;
char word[30];
// (1) Read all words
in = fopen(infile, "r"); // .. and enforce success
while (fscanf(in, "%29s", word) == 1) {
// store word somewhere
}
fclose(in);
// (2) Determine unique words somehow
// (3) Write out unique words
out = fopen(outfile, "w"); // .. and enforce success
for (i = 0; i < nunique; i++) {
fprintf(out, "%s\n", unique[i]);
}
fclose(out);
return 0;
}
The actual algorithm to fin the unique words is missing from this incomplete skeleton code.
If you really want to test the words in a file for uniqueness without using additional memory beyond the current word, you can open the input file twice, with independent file pointers. Then you can write a loop like so:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
const char *infile = "text.txt";
const char *outfile = "norep.txt";
FILE *in1;
FILE *in2;
FILE *out;
char word1[30];
char word2[30];
in1 = fopen(infile, "r");
in2 = fopen(infile, "r");
out = fopen(outfile, "w");
if (in1 == NULL || in2 == NULL || out == NULL) {
fprintf(stderr, "Could not open all required files.\n");
exit(1);
}
while (fscanf(in1, "%29s", word1) == 1) {
int count = 0;
while (fscanf(in2, "%29s", word2) == 1) {
if (strcmp(word1, word2) == 0) count++;
if (count > 1) break;
}
if (count == 1) fprintf(out, "%s\n", word1);
rewind(in2);
}
fclose(in1);
fclose(in2);
fclose(out);
return 0;
}
This will, of course, re-read the file as often as there are words in the file. Not a good approach to find the unique words in Moby-Dick. I recommend that you look into the memory-based approach.

In C, how to print out a txt file line by line?

int main()
{
FILE *infile;
FILE *infile2;
char input[255],input2[255];
int status1, status2;
infile = fopen("test.txt", "r");
infile2 = fopen("test2.txt", "r");
if(infile == NULL)
{
printf("Can not open file 1!\n");
}
else if(infile2 == NULL)
{
printf("Can not open file 2!\n");
}
else
{
do
{
status1 = fscanf(infile, "%s", &input);
status2 = fscanf(infile2, "%s", &input2);
printf("File 1: %s\n File 2: %s\n", input, input2);
}while(status1 != -1 || status2 != -1);
}
fclose(infile);
fclose(infile2);
return 0;
}
My output looks like this:
Output
I would like to print out file 1 in one line not word by word. The same goes for file2. I'm kinda new to C so I'm stuck.
If you would like to read the entire line, use fgets function instead of fscanf:
char *status1, *status2;
.
.
.
do {
status1 = fgets(input, sizeof(input), infile);
status2 = fgets(input2, sizeof(input2), infile2);
printf("File 1: %s File 2: %s", input, input2);
} while (status1 || status2);
Note how printf no longer uses \n. This is because fgets keeps \n from the file inside your input string.
I made the changes to the code and it works, but another question. If i wanted to compare the files and write out the differnce to a new file like this:
File1: My name is Knut
File2: My name is KnutAndre
File3: Andre (This is the differnce between the files).
My teacher told me to use strcmp and then get the output into a new file, but i dont quite understand him.. Does anyone have some tips that i could try out?
This is how my code look so far:
int main()
{
FILE *infile;
FILE *infile2;
FILE *outfile3;
char input[255],input2[255];
char status1, status2;
infile = fopen("test.txt", "r");
infile2 = fopen("test2.txt", "r");
if(infile == NULL)
{
printf("Can not open file 1!\n");
}
else if(infile2 == NULL)
{
printf("Can not open file 2!\n");
}
else
{
do
{
status1 = fgets(input, sizeof(input), infile);
status2 = fgets(input2, sizeof(input2), infile2);
if(status1 != 0){
printf("File 1: %s\n\nFile 2: %s\n\n", input, input2);
int result = strcmp(input, input2);
printf("\nResult = %d\n\n", result);
}
}
while(status1 || status2);
}
fclose(infile);
fclose(infile2);
return 0;
}
When you are using the fscanf it will only read the characters until the non white space character occurs. When you need to get the input as whole line then you have to use fgets().
From the man page of fgets().
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character
in the buffer.
So you have to use like this.
fgets(input,255,infile);
fgets(input2,255,infile2);
While checking condition,
while(input != NULL || input2 != NULL);
In my school, we make a get_next_line function, who takes a file descriptor and a pointer to a string in parameter.
you can take a look here : https://github.com/juschaef/libtowel/search?utf8=%E2%9C%93&q=get+next+line

Reading in multiple data files from a mapping file in C

First off I am creating a program that will read lines of characters and find words (they don't have to have meaning, i.e 'ab' could be word ) and storing them in the appropriate data structure. I used trie structure to store the words. I am given a mapping file as a command line argument yet inside the mapping file I have two data files I need to gain information from. The usage interface is as follows: first(program name) <mappingfile>.
Inside the mapping file, there exists two data files: <dictFile> and <dataFile>. Im not sure how to read and store the information presented the two data files. So far I have the following:
#include <stdio.h>
#include<stdlib.h>
void readDict(FILE *dict_file){
}
int main(int argc, char *argv[]){
FILE* file;
if(argc != 2){ //error in inputing, not 2 files
printf("error\n");
return 0;
}
file = fopen(argv[1],"r" ); //reading the mapping file
input;
if(file == NULL){ //nothing inside file
printf("file does not exist\n");
return 0;
}
}
My goal is to have pointers point to respective data files in the mapping file which I can use for reading their contents.
I will be given the following input in the command line:
first(program name) <mappingfile>.
Inisde the mapping file contains the lines of two plain .txt files in the form
<dictFile> <dataFile>.
I wish to access both contents of <dictFile> and <dataFile>.. with pointers to the respective file.
If I understand your question correctly you want to parse a file where each line contains the filenames of two other files and then read from these. What you can do is use fgets to read your mapping file line by line. What you can do next is use the function strtok to split your string on a whitespace. I'll break it down for you step by step.
Firstly we want to open the mapping file for reading
if((file = fopen(argv[1],"r")) == NULL) {
perror("error opening file");
return 1;
}
This will try to open the mapping file specified by the command line arguments of your program and if it fails it will print a corresponding error message.
while(fgets(buf, sizeof(buf), file) != NULL) {
After we've opened the file we want to iterate through all the lines until we reach the end of the file and fgets will return NULL. fgets will put the current line into buf.
dictfilename = strtok(buf, " ");
datafilename = strtok(NULL, " ");
strtok(dictfilename, "\n"); /* Remove any trailing newlines */
strtok(datafilename, "\n");
We need to split the line read by fgets by a delimter (a whitespace) so we know which part corresponds to the dictfile and the datafile. This is done by using the strtok function which returns a pointer to the substring before the whitespace and when passing in NULL it will return a pointer to the substring after the whitespace. A slightly weird way of removing any trailing newlines is to use strtok and the newline as a delimiter.
if((dictfile = fopen(dictfilename,"r")) == NULL) {
fprintf(stderr, "error opening file %s: %s\n", dictfilename, strerror(errno));
return 1;
}
if((datafile = fopen(datafilename,"r")) == NULL) {
fprintf(stderr, "error opening file %s: %s\n", datafilename, strerror(errno));
return 1;
}
Very similiarly to how we open the mapping file, we now open the two files found on the current line read by fgets with "r" mode which opens for reading. If the file does not exist or cannot be found, the fopen call fails.
printf("Content of %s:\n", dictfilename);
while ((c = getc(dictfile)) != EOF)
putchar(c);
printf("\nContent of %s:\n", datafilename);
while ((c = getc(datafile)) != EOF)
putchar(c);
This is a very simple method of "dumping" the content of the files. It uses getc to read the next char from the file and prints it until it reads EOF. This is where you should do your own function.
fclose(dictfile);
fclose(datafile);
And don't forget to close the files afterwards or you will leak resources.
Finally here is the code on what I just described
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define MAX_LENGTH 100 // change this to the actual maximum length of your lines.
int main(int argc, char **argv){
FILE* file, *dictfile, *datafile;
char c;
char buf[MAX_LENGTH];
char *dictfilename, *datafilename;
if(argc != 2) {
fprintf(stderr, "Usage: %s <mapping file>\n", argv[0]);
return 0;
}
if((file = fopen(argv[1],"r")) == NULL) {
perror("error opening file");
return 1;
}
while(fgets(buf, sizeof(buf), file) != NULL) {
dictfilename = strtok(buf, " ");
datafilename = strtok(NULL, " ");
strtok(dictfilename, "\n"); /* Remove any trailing newlines */
strtok(datafilename, "\n");
if((dictfile = fopen(dictfilename,"r")) == NULL) {
fprintf(stderr, "error opening file %s: %s\n", dictfilename, strerror(errno));
return 1;
}
if((datafile = fopen(datafilename,"r")) == NULL) {
fprintf(stderr, "error opening file %s: %s\n", datafilename, strerror(errno));
return 1;
}
// do something with the files (e.g read all the content)
printf("Content of %s:\n", dictfilename);
while ((c = getc(dictfile)) != EOF)
putchar(c);
printf("\nContent of %s:\n", datafilename);
while ((c = getc(datafile)) != EOF)
putchar(c);
printf("\n");
// don't forget to close the files when you're done with them.
fclose(dictfile);
fclose(datafile);
}
fclose(file);
}
If I understand you correctly this should do it. Note that it assumes your filenames don't have any spaces. And if you want to use the "non secure" api's you need to add _CRT_SECURE_NO_WARNINGS to the project properties under Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions.
#include <stdio.h>
#include<stdlib.h>
void readDict(FILE *dict_file){
}
int main(int argc, char *argv[]){
FILE* file;
if(argc != 2){ //error in inputing, not 2 files
printf("error\n");
return 1;
}
file = fopen(argv[1],"r" ); //reading the mapping file
//input;
if(file == NULL){ //nothing inside file
printf("file does not exist\n");
return 1;
}
char dictFileString[256], dataFileString[256];
fscanf( file, "%255s %255s", dictFileString, dataFileString );
FILE *dictFile, *dataFile;
dictFile = fopen( dictFileString, "r" );
if (dictFile == NULL) {
printf( "%s does not exist\n", dictFileString );
fclose(file);
return 1;
}
dataFile = fopen( dataFileString, "r" );
if (dataFile == NULL) {
printf( "%s does not exist\n", dataFileString );
fclose(file);
fclose(dictFile);
return 1;
}
readDict(dictFile);
// The additional logic would be placed here.
fclose( dictFile );
fclose( dataFile );
// If you need to read additional file names then loop
// back up to read the next line of 'file'
fclose( file );
return 0;
}

Copy from one txt file to another with c

I am having problems with copying txt files. I need to info from one file to another.
My code looks like this,
_tprintf (TEXT("%s\n"), FindFileData.cFileName);
memset(fileName, 0x00, sizeof(fileName));
_stprintf(fileName, TEXT("%s\\%s"), path, FindFileData.cFileName); //iegust
FILE *fptr = fopen(fileName, "r");//atver
fscanf(fptr,"%[^\n]",c); //iegust datus no faila
printf("Data from file:\n%s",a);
strcpy(a, c); //nokope datus
buffer2 = strtok (c, ","); //norada partraukumu un tadas lietas
while (buffer2) {
buffer2 = strtok (NULL, ",");
if(i<1){ printf("%s\n", c);}
i++;
while (buffer2 && *buffer2 == '\040'){
buffer2++;
// TODO ieliec iekavinas
}
}
And after that I use basic fputs().
My problem is that this code ignores new lines. It prints out fine, each string in it's own line, but that does not happen in file. (\n).
Your problem is that you just need to copy information from one file to another. So, why you don't use a simple solution to do it than your. I have a snipet code can solve your problem easily as shown below.
If I am wrong about your question, please give me advices.
#include <stdio.h>
#include <stdlib.h> // For exit()
int main()
{
FILE *fptr1, *fptr2;
char filename[100], c;
printf("Enter the filename to open for reading \n");
scanf("%s", filename);
// Open one file for reading
fptr1 = fopen(filename, "r");
if (fptr1 == NULL)
{
printf("Cannot open file %s \n", filename);
exit(0);
}
printf("Enter the filename to open for writing \n");
scanf("%s", filename);
// Open another file for writing
fptr2 = fopen(filename, "w");
if (fptr2 == NULL)
{
printf("Cannot open file %s \n", filename);
exit(0);
}
// Read contents from file
c = fgetc(fptr1);
while (c != EOF)
{
fputc(c, fptr2);
c = fgetc(fptr1);
}
printf("\nContents copied to %s", filename);
fclose(fptr1);
fclose(fptr2);
return 0;
}

Problems with readdir() and fgets

I'm writing a code where I can be given a directory of .txt files, and specific strings that appear throughout each file, and do some simple comparisons. code chunk will be posted below.
So, My task:Open directory>open file>compare strings>open next file(repeat)
Until I run out of files.
What is wrong:My code currently prints the first file name( full path name) infinitely until it crashes, nothing is printed to fp1. It is supposed to only print the file name once, but it never gets past that first file, where, obviously, I would like it to go through all the files in the directory.
I'm sorry that I'm fairly new to C so I might be unclear as to how these functions actually operate.
Please correct me if I'm wrong, I want to see if I understand correctly.
while ((in_file = readdir(FD))!= NULL){
Should basically traverse through a directory and "look" the name of each file.
I then do some very inefficient work around, which you will probably laugh at me for, and I manage to get the full path name of the first file in the directory.
I then assign that path name to entry_file pointer, where it gets opened by fgets().
I believe fgets() should read each line individually until it sees a EOF character
Now, I had this section working before I added the directory stuff, where I was just opening one file by using fopen() with its full path name, and I haven't touched it. So I don't think my problem is here, but nothing is being printed to fp1 at all, so I really don't know.
I then do some simple string comparisons and try to print matches to fp1
When it reaches the end of the file, it should close the file, and then go back up to readdir() and repeat the process with the next file
Thank you so much for any help. I probably sound like an idiot, but I just have no idea what could cause this.
Yes, I realize its very messy, and I have many unused and pointless variables. I've been trying to figure this out for days, trying many different methods.
int main(void)
{
char str1[10000];
char str2[] = { "Measure L1 current Tank Heater ON: Passed" };
char str3[] = { "Measure L1 current Tank Heater ON: Failed" };
char str4[] = { "Measure L1 current Manifold Heater ON: Passed" };
char str5[] = { "Measure L1 current Manifold Heater ON: Failed" };
char str6[] = { "Measure L1 current (verify heaters off) Manifold: Passed" };
char str7[] = { "Measure L1 current (verify heaters off) Manifold: Failed" };
char sn[] = { "Serial Number: 1" };
DIR* FD;
struct dirent* in_file;
int lcount = 0;//line counter
char *ret;
int linenum = 0;//temp line count
char mes[500];//measurement
double val = 0;//value
char unit[500];//units
char pathstr1[38] = ("C:/Users/liam.king/Desktop/TestFiles/");
char pathstr2[200];
DWORD retval = 0;
char buffer[BUFSIZE] = ("");
char buf[BUFSIZE] = ("");
char** lppPart = {NULL};
FILE *fp, *fp1, *filewrite;
FILE *entry_file;
//fp = fopen("C:/Users/liam.king/Desktop/TestFiles/ProBlueUnit_UpgradeRev4_Report[1022230.SA15E14082][9 39 00 AM][5 19 2015].txt", "r");
fp1 = fopen("C:/Users/liam.king/Desktop/ProBlueTestWrite.txt", "a");
filewrite = fopen("C:/Users/liam.king/Desktop/FileWrite.txt", "w+");
if (fp1 == NULL){
printf("Invalid file name");
return 0;
}
if ((FD = opendir(LONG_DIR_NAME))==NULL)
{
printf("Error: Failed to open directory\n");
return 0;
}
else{
printf("Directory opened successful\n");
}
while ((in_file = readdir(FD))!= NULL){
if (strcmp(in_file->d_name, ".") == 0 || strcmp(in_file->d_name, "..") == 0)
continue;
fprintf(filewrite, "%s", pathstr1);
fprintf(filewrite,"%s", in_file->d_name);
fclose(filewrite);
filewrite = fopen("C:/Users/liam.king/Desktop/FileWrite.txt", "r");
fscanf(filewrite, "%[^\n]%*c", pathstr2);
printf("%s\n", pathstr2);//check file name is correct
entry_file = fopen(pathstr2, "r");
fclose(filewrite);
if (entry_file != NULL){
//printf("SUCCESSFULL OPENING\n");
//fprintf(fp1, "Does this work?\n");
}
else if (entry_file == NULL){
printf("Error: Failed to open entry file\n");
return 0;
}
while (fgets(buffer, 256, entry_file) != NULL){//string being stored in str1 from file *entry_file
lcount++;
ret = strstr(str1, sn);
if (ret != NULL){
fprintf(fp1, "%s\n", str1);
}
ret = strstr(str1, str2);
if (ret != NULL){// compares str1 and 2
fprintf(fp1, "Found"" %s ""at line %d\n", str1, lcount);//if same, declare match and what line found at.
linenum = lcount;
}
//comparing more strings
}
fclose(entry_file);
}
fclose(fp1);
return 0;
}
Since pathstr2 is declared as a local array, you should use this:
while ((in_file = readdir(FD)) != NULL) {
if (!strcmp(in_file->d_name, ".") || !strcmp(in_file->d_name, ".."))
continue;
snprintf(pathstr2, sizeof(pathstr2), "%s%s", pathstr1, in_file->d_name);
entry_file = fopen(pathstr2, "r");
...
while (fgets(buffer, sizeof(buffer), entry_file) != NULL) {
lcount++;
if (strstr(buffer, sn)) {
fprintf(fp1, "%s", buffer);
}
if (strstr(buffer, str1)) {
fprintf(fp1, "Found \"%s\" at line %d\n", str1, lcount);
linenum = lcount;
}
...
}
fclose(entry_file);
}
The tests you perform with strstr on the lines read from entry_file are not incorrect. You should specify buffer instead of str1 as the first argument.
Also note that strstr searches for the second string in the whole line. If the string should be starting at the beginning of the line, you should write:
if (!strncmp(buffer, str1, strlen(str1))) {
// line starts with str1
}

Resources