Been looking in to C and I'm working on a simple program to read a text file, apply a caesar cipher, and write to a new output file. My problem is that the while-loop supposed to build my output string terminates immediately, claiming that the next character is EOF, even when it obviously isn't. Code below:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define MORD ".mord"
void die(const char *message)
{
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
int main(int argc, char *argv[])
{
if(argc != 3) die("USAGE: dodsmord <filename> <offset>");
char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
int offset = atoi(argv[2]);
char *outstr[1000];
FILE *infile = fopen(infilename, "r+");
FILE *outfile = fopen(outfilename, "w+");
if(infile == NULL) {
die("Could not open input file");
}
if(outfile == NULL) {
die("Could not open output file");
}
int c;
int i = 0;
printf("reading input file...\n");
while(1) {
c = fgetc(infile);
printf("c == EOF: %d\n", c == EOF ? 1 : 0);
printf("EOF: %d\n", EOF);
printf("c is now: %c\n", c);
if(c == EOF) break;
outstr[i] = c + offset;
i++;
}
printf("done reading! writing outstr to outfile...\n");
fwrite(outstr, sizeof(char), i, outfile);
printf("closing streams...\n");
fclose(infile);
fclose(outfile);
return 0;
}
The output if I run the code on test.txt (which contains exactly "abcdefg" without quotes), I get the output
reading input file...
c == EOF: 1
EOF: -1
c is now: �
done reading! writing outstr to outfile...
closing streams...
char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
This doesn't do what you think it does.
It sets up infilename so that it points to the same memory as argv[1], then the strcat changes that memory to append the .mord.
Then it returns it so that outfilename also points to the memory.
Hence you're changing the input file name to be the .mord one and, when you try to open it, well, I don't know what will happen exactly, it depends on whether it exists yet.
What you want is something like:
char *infilename = argv[1];
char *outfilename = malloc (strlen (infilename) + strlen (MORD) + 1);
if (outfilename == NULL) {
handleOutOfMemoryHere();
}
strcpy (outfilename, infilename);
strcat (outfilename, MORD);
:
// weave you cypher magic here
:
free (outfilename);
The second line in that code will give you a separate memory area for the output file name and the strcpy/strcat combo will construct it correctly.
Here is the problem:
char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
strcat() will change infilename, and append that MORD to the end of it, therefore you are using argv[1].mord as your input file name. I bet it is a empty file.
Solution:
Change
char *outfilename = strcat(infilename, MORD);
to
char *outfilename = malloc(strlen(infilename) + strlen(MORD) + 1);
if (outfilename == NULL) { /* malloc failed */ }
strcpy(outfilename, infilename);
strcat(outfilename, MORD);
The problem is caused by:
char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
Reason: strcat does a in-place copy and returns the address of src. Try this and you would see:
char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
printf("TEST: %p %p\n", infilename, outfilename);
To fix this, use something like this:
char *infilename = argv[1];
char *outfilename = malloc(strlen(infilename) + strlen(MORD) + 1);
strcpy(outfilenname, infilename);
strcat(outfilename, MORD);
problem is with below line
char *outfilename = strcat(infilename, MORD);
infilename is getting modified to test.txt.mord
Move
FILE *infile = fopen(infilename, "r+");
above the following line
char *outfilename = strcat(infilename, MORD);
Related
The programm should be able to open a file like myFile.txt,
alltough it's real name is myFile without the extension .txt.
So I wrote the function called removeFileExtension() in order
to achieve that.
It does open my file by copying the string from text into filename:
strcpy(filename,text);
FILE *fp = fopen(filename, "r");
So I tried to check what the difference between text and my processed
string from removeFileExtension is.
To check if it even works I mate a function called strComparison(),
which returns either 0 when it is qual or 1 if unequal.
The thing is, after removing the file extension, it shows that both strings
are qual, but I am still not able to open the file.
When I type in ./a.out myFile.txt my comparison function returns 0,
it is equal, but fopen() still is not able to open the file,
respectively I allways get a Segmentation fault.
Does anyone see the problem here?
Why am I getting a Segmentation fault?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void removeFileExtension(char *haystack);
int strComparison(char *one, char *two);
int main(int argc, char const *argv[])
{
//----------------------------------------------------------------------------
// CHECK INPUT VALIDITY
//
if (argc != 2)
{
printf("Usage: ./ass2 [file-name]\n");
return 1;
}
//----------------------------------------------------------------------------
// OPEN FILE (INITIAL)
//
char filename[32];
strcpy(filename, argv[1]);
FILE *fp = fopen(filename, "r"); //FOPEN
//FILE *fp = fopen("start_of_story\0txt", "r"); // this way does work
if (fp == NULL)
{
// IF NOT FOUND: REMOVE EXTENSION
removeFileExtension(filename);
char text[] = "myFile\0";
int ret_val = -1;
ret_val = strComparison(filename, text);
if (ret_val == 0)
printf("[DEBUG] equal\n");
else
printf("[DEBUG] unequal\n");
printf("[DEBUG] ret_val: %d\n", ret_val);
printf("[DEBUG] '%s'\n", filename);
FILE *fp = fopen(filename, "r"); //FOPEN
// IF STILL DOESN'T WORK: ERROR
if (fp == NULL)
{
printf("[ERR] Could not read file %s.\n", filename);
return 3;
}
}
//--------------------------------------------------------------------------
// READ DATA (INITIAL)
//
int bufsize = 1024;
char *buffer = malloc(bufsize * sizeof(char)); //MALLOC
if (!buffer)
{
printf("[ERR] Out of memory.\n");
return 2;
}
fseek(fp, 0, SEEK_SET);
fread(buffer, bufsize, 1, fp);
printf("[DEBUG] %s\n", buffer);
fclose(fp); //FCLOSE
free(buffer);
buffer = NULL;
return 0;
}
void removeFileExtension(char *haystack)
{
char needle[1] = ".";
char *retp; // return pointer
retp = strstr(haystack,needle);
if (*retp == '.')
{
while (*retp != '\0')
{
*retp++ = '\0';
}
printf("[DEBUG] %s\n", haystack);
}
}
int strComparison(char *one, char *two)
{
do
{
printf("[DEBUG] '%c' == '%c'\n", *one, *two);
if (*one++ != *two++)
{
return 1; // return 1 if unqual
}
}
while ( (*one != '\0') || (*two != '\0') );
return 0; // return 0 if qual
}
Resulting output:
user#host ~/Desktop $ ./a.out myFile.txt
[DEBUG] myFile
[DEBUG] 'm' == 'm'
[DEBUG] 'y' == 'y'
[DEBUG] 'F' == 'F'
[DEBUG] 'i' == 'i'
[DEBUG] 'l' == 'l'
[DEBUG] 'e' == 'e'
[DEBUG] equal
[DEBUG] ret_val: 0
[DEBUG] 'myFile'
[ERR] Could not read file myFile.
user#host ~/Desktop $
Quoting C11, chapter 7.24.5.7
char *strstr(const char *s1, const char *s2);
The strstr function locates the first occurrence in the string pointed to by s1 of the
sequence of characters (excluding the terminating null character) in the string pointed to
by s2.
So, both the arguments passed to strstr has to be strings. In your case,
char needle[1] = ".";
is not a string. You did not allow the space for the null-terminator. Either use
char needle[2] = ".";, at least, or,
char needle[ ] = ".";, or,
char const* needle = ".";
As a side effect, whenever the call to removeFileExtension() is reached, you'll face with undefined behavior
That said, beware!!
You are doing something like
retp = strstr(haystack,needle);
if (*retp == '.')
i.e., dereferencing the returned pointer from strstr(). If, strstr() returns a NULL pointer, you'll again be trapped in UB.
EDIT:
For those who still has confusion about string, check definition in chapter §7.1.1 (emphasis mine)
A string is a contiguous sequence of characters terminated by and including the first null
character. [...]
At least I found the problem:
After removing the file's extension, I am still
trying to open the old file pointer fp, which
gave me the NULL-pointer back. The new file pointer
inside the body of the if(fp == NULL){...} only
exists inside the scope of the if-statement.
So I created a test_pointer, which first looks if
the file even exists, if not, he removes the extension.
Than I try again to open the file, this time with fp.
Thanks to everybody for the hints, especially to
Sourav Ghosh
for your improvement suggestions!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int removeFileExtension(char *haystack);
int main(int argc, char const *argv[])
{
char filename[64];
strcpy(filename, argv[1]);
//----------------------------------------------------------------------------
// CHECK INPUT VALIDITY
//
if (argc != 2)
{
printf("Usage: ./ass2 [file-name]\n");
return 1;
}
//----------------------------------------------------------------------------
// CHECK FILE EXISTENSE
//
FILE *test_pointer = fopen(filename, "r"); //FOPEN
if (test_pointer == NULL) // if not found: remove extension
{
int ret_val = removeFileExtension(filename);
if (ret_val == -1)
{
printf("[ERR] Could not remove file extension.\n");
return 3;
}
}
//----------------------------------------------------------------------------
// OPEN FILE (INITIAL)
//
FILE *fp = fopen(filename, "r"); //FOPEN
if (fp == NULL) // if still doesn't work: error
{
printf("[ERR] Could not read file %s.\n", filename);
return 3;
}
//----------------------------------------------------------------------------
// READ DATA (INITIAL)
//
int bufsize = 1024;
char *buffer = malloc(bufsize * sizeof(char)); //MALLOC
if (!buffer)
{
printf("[ERR] Out of memory.\n");
return 2;
}
fseek(fp, 0, SEEK_SET);
fread(buffer, bufsize, 1, fp);
fclose(fp); //FCLOSE
printf("[DEBUG] %s\n", buffer);
free(buffer); //FREE
buffer = NULL;
return 0;
}
int removeFileExtension(char *haystack)
{
char needle[] = ".";
char *retp; // return pointer
retp = strstr(haystack,needle);
if(!retp) // to prevent UB
return -1;
if (*retp == '.')
{
while (*retp != '\0')
{
*retp++ = '\0';
}
printf("[DEBUG] %s\n", haystack);
}
return 0;
}
I'm trying to read a file and store its content in a variable, here's my code:
#define _BSD_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
// CEK ROUTER MODEL
char* router_model;
char* model() {
char filename[] = "/tmp/cpuinfo";
char* key = "system type";
char* value;
FILE *file = fopen(filename, "r");
if (file != NULL) {
char line[1000];
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
router_model = strdup(value);
break; // once the key has been found we can stop reading
}
}
fclose(file);
}
else {
perror(filename); //print the error message on stderr.
}
return router_model;
}
// TULIS SERIAL NUMBER KE FILE
char tulis(char p[100]) {
// Write a serial number to a file
char sn[30];
char encrypt_sn[300];
printf("Serial Number:\n");
scanf("%s", sn);
FILE *f = fopen("/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", "w");
if (f == NULL) {
printf("Error opening file!\n");
exit(1);
}
fprintf(f,"Serial Number: %s", sn);
fclose(f);
sprintf(encrypt_sn, "ccrypt -e /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c -K %s", p);
system(encrypt_sn);
system("mv /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c");
printf("Serial number is saved in /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c\n");
return 0;
}
// BACA SERIAL NUMBER & SIMPAN DALAM SEBUAH VARIABLE
char baca(char p[100]) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[300];
char key[30] = "Serial Number";
char *serial_number;
if( access( "/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
serial_number = strdup(value);
break; // once the key has been found we can stop reading
}
}
fclose(file);
//printf("Your hardware serial number is: (%s)\n", serial_number);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
return -1;
}
return 0;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
original_sn = baca(p);
printf("SN: %s\n", original_sn);
return 0;
}
The file is /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c and the content of that file is Serial Number: 1866203214226041 and original_sn should output 1866203214226041. However when I run that code I get:
test.c: In function ‘main’:
test.c:105:14: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
original_sn = baca(p);
^
SN: (null)
How do I fix it ?
This happens because your baca function returns a char, whereas you are assigning its return value to a char *. Maybe you wanted to use a char variable.
If function baca can change the contents of the memory block pointed by the input argument:
Change this:
char* p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
To this:
char p[] = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
If function baca cannot change the contents of the memory block pointed by the input argument:
Change this:
char baca(char p[])
To this:
char baca(const char* p)
In baca you are allocating initialised memory using strdup:
serial_number = strdup(value);
, then you do nothing with that.
It is clear that you think that the function returns a pointer to that memory so you can print it's content. However, it is not what you are doing. Because all your baca function is doing is returning a value indecating if it sucseede (0) or not (-1). And you are jut ignoring that pointer and leaving some wasted unused memory allocated by your prog.
Their are 2 methodes to fix your code:
Method1 : returning the serial_number
char* baca(const char* p) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[300];
char key[30] = "Serial Number";
char *serial_number=NULL;
if( access( "/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
if(value!=NULL){/*testing the return value for erros so you prog doesn't cruch*/
value += 2;
serial_number = strdup(value);
}
/*in case off erreor you can choose one of two options:*/
/*optinon1: print an error mesage then kill your prog*/
else{
printf("Error: corrupted file!\n");
exit(1);
}
/*option 2: removing the else part your baca then will return NULL and the calling code should understand that an error has occured*/
break;
}
}
fclose(file);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
}
return serial_number;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
original_sn = baca(p);
if(original_sn!=NULL){
printf("SN: %s\n", original_sn);
free(original_sn);/*you should free the memory allocated by strdup once you are done using it.*/
}
else{
printf("An error has occured\n");
}
return 0;
}
Method2 : pass by reference
char baca(const char* p, char **serial_number) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[300];
char key[30] = "Serial Number";
char ret = 0;/*the return value 0 means no error.*/
if( access( "/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
if(value!=NULL){/*testing the return value for erros so you prog doesn't cruch*/
value += 2;
*serial_number = strdup(value);
}
/*in case off erreor you can choose one of two options:*/
else{
/*optinon1: print an error mesage then kill your prog*/
/*option 2: making the return value non 0 and the calling code should understand that an error has occured*/
#define OPTION1
#ifdef OPTION1
printf("Error: corrupted file!\n");
exit(1);
#else
ret=-2; //to used this option comment out #define OPTION1
#endif
}
break;
}
}
fclose(file);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
ret=-1;
}
return ret;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn=NULL;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
switch(baca(p,&original_sn))
{
case 0: //evrything is fine
printf("SN: %s\n", original_sn);
free(original_sn);
break;
case -1:/* handle each error as you should*/
case -2:
default:
printf("An error has occured\n");
}
return 0;
}
Hope this helps. :).
I have looked for an answer to my question for almost two days and tried every solution suggested to no avail.
I am trying to access a file through a linux terminal using my C Program.
I want to run popen() to do this.
The command I want to run in popen() is : grep -o %s /usr/share/dict/words
Where %s is a variable word that changes each iteration. I have tried using pointers, arrays, and alternative functions such as asprintf() / snprintf()
Here is the code I have right now:
char *message = (char *)malloc(500);
strcpy(message, "grep -n");
printf("%s", message);
strcat(message, "hello");
printf("%s", message);
strcat(message, " /usr/share/dict/words"); // SEG FAULT OCCURS HERE
printf("%s", message);
I would then pass this to popen.
I have also tried initializing as: char message[500] and this returns the same error in the same spot.
Here is my full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "caeserheader.h"
int main( int argc, char *argv[]){
char *inputfile;
int n = 0;
int shiftamount = 0;
//Determine amount of arguments
if(argc == 2){
inputfile = argv[1];
}
else if(argc == 3){
inputfile = argv[1];
n = atoi(argv[2]);
shiftamount = n * (-1) ;
}
else{
printf("Please enter a proper number of arguments.");
return -1;
}
//OPENS INPUT FILE
FILE *input = fopen(inputfile, "r");
if(input == NULL){
printf("\n FILE NOT FOUND.");
perror("fopen");
return -1;
}
//RESERVES MEMORY AND GRABS STRING
fseek(input, 0L, SEEK_END);
long Tsize = ftell(input);
rewind(input);
char *inputtext;
inputtext = calloc( 1, Tsize+1);
//ERROR CHECKING
if(!inputtext){
fclose(input), printf("MEMORY FAILED.");
}
if(1!=fread( inputtext, Tsize, 1, input)){
fclose(input), free(inputtext), printf("READ FAIL.");
}
//CREATES DECRYPTED STRING
char newletter;
char *newstring;
int i;
//WITH GIVEN NUMBER OF SHIFTS
if(argc == 3){
newstring = malloc(Tsize + 1);
for(i=0; i<Tsize; i++){
newletter = shift(inputtext[i], shiftamount);
newstring[i] = newletter;
}
}
//WITHOUT GIVEN NUMBER OF SHIFTS
if(argc == 2){
char *message = (char *)malloc(500); //SEG FAULT SOMEWHERE HERE?
// strcpy(message, "grep -n");
// printf("%s", message);
//strcat(message, "hello");
// printf("%s", message);
// strcat(message, "/usr/share/dict/words");
//printf("%s", message);
// word = strtok(inputtext," ,.-!?\n");
// int i;
//for(i=0; i<10; i++){
//word = strtok(NULL," ,.-!?\n");
//printf("\n%s", word);
//}
// if(( fp = popen(message, "r")) == NULL){
//perror("No file stream found.");
//return -1;
// }
// else {
// pclose(fp);
// printf("FOUND.");
// }
}
// PUTS DECRYPTED STRING IN NEW FILE
char copiedname[100];
strcpy(copiedname, inputfile);
strcat(copiedname, ".dec");
FILE *newfile = fopen(copiedname, "w");
fputs(newstring, newfile);
// free(newstring);
fclose(input);
fclose(newfile);
return 0;
}
You have set inputfile to argv[1] and later you have used strcat to append to it. Don't do this. You don't own argv.
The strcat function appends a copy of the source string to the destination string, and then returns a pointer to the destination string. It does not "add two strings and return the result" which is how you seem to be using it.
For this problem I'm asked to first read from the input text file, prompt the user which word/string to get replaced, then output the same file (the original gets overwritten). The thing is the input/outputfile name must always have a specific name for example test.txt (this is what bothers me)
Here's the function which I tested out and it does the job replacing, but for now I'm prompting user to enter their own "sentence" and then for words. I'm lost on how to (always) read from a test.txt and then output the same one with replaced string.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *w_replace(const char *s, const char *oldone, const char *newone)
{
char *ret;
int i, count = 0;
int newlen = strlen(newone);
int oldonelen = strlen(oldone);
for (i = 0; s[i] != '\0'; i++)
{
if (strstr(&s[i], oldone) == &s[i])
{
count++;
i += oldonelen - 1;
}
}
ret = (char *)malloc(i + count * (newlen - oldonelen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s)
{
if (strstr(s, oldone) == s) //compare
{
strcpy(&ret[i], newone);
i += newlen;
s += oldonelen;
}
else
ret[i++] = *s++;
}
ret[i] = '\0';
return ret;
}
int main(void)
{
char mystr[100], c[10], d[10];
char fileOld[32] = "test.txt";
char fileNew[32] = "test.txt";
char word_search[80];
char word_replace[80];
FILE *fp1, *fp2;
fp1 = fopen(fileOld,"r");
fp2 = fopen(fileNew,"w");
printf("Enter the word to replace :\n");
scanf(" %s",word_search);
printf("Enter the new word:\n");
scanf(" %s",word_replace);
char *newstr = NULL;
newstr = w_replace(fileOld, word_search , word_replace);
fputs(word_replace, fp2);
fclose(fp2);
fclose(fp1);
return 0;
}
So if a test.txt contains the following sentence
This is a test
Result
Enter the word to replace :
This
Enter the new word:
That
The new updated test.txt file will only be
That
instead of
That is a test
Needed values (using the var names you gave above):
#include <fcntl.h>
int file_descriptor;
int size_of_text = <whatever you want here>;
char *file_name = "test.txt";//or whatever
char newone[size_of_text];
char oldone[size_of_text];
To read from a file:
file_descriptor = open(file_name,O_RDONLY);//O_RDONLY opens for read only
read(file_descriptor,oldone,sizeof(oldone));//reads file into oldone
close(file_descriptor);//closes so you don't accidentally read or write to it later, and so you can use it again
To write to a file:
file_descriptor = open(file_name,O_WRONLY | O_TRUNC);//O_WRONLY opens for writing only, O_TRUNC will truncate the file if it exists
write(file_descriptor,newone,sizeof(newone);//writes newone to file
close(file_descriptor);
For more information on read(),write(),open(),close():
http://www.gdsw.at/languages/c/programming-bbrown/c_075.htm
I want to make a program that delete a String that the same as user input from a file
below are contents in the file
G12
G13
G14
For example user input G13 , expected output is as following :
G12
G14
I got some idea that make a temporary file , but don't get any idea on how to get a string line by line because i print the file content using these code
if(file!=NULL)
{
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
so basically i reads all the file content only letter by letter (dont have any idea how to make it reads word by word
Thanks in advance
simple line by line sample
#include <stdio.h>
#include <string.h>
char *esc_cnv(char *str){
char *in, *out;
out = in = str;
while(*in){
if(*in == '\\' && in[1] == 'n'){
*out++ = '\n';
in += 2;
} else
*out++ = *in++;
}
*out = '\0';
return str;
}
int main(void){
FILE *fin = stdin, *fout = stdout;
char line[1024];
char del_str[1024];
char *p, *s;
int len;
int find=0;//this flag indicating whether or not there is a string that you specify
fin = fopen("input.txt", "r");
fout = fopen("output.txt", "w");//temp file ->(delete input file) -> rename temp file.
printf("input delete string :");
scanf("%1023[^\n]", del_str);
esc_cnv(del_str);//"\\n" -> "\n"
len = strlen(del_str);
while(fgets(line, sizeof(line), fin)){
s = line;
while(p = strstr(s, del_str)){
find = 1;//find it!
*p = '\0';
fprintf(fout, "%s", s);
s += len;
}
fprintf(fout, "%s", s);
}
fclose(fout);
fclose(fin);
if(find==0)
fprintf(stderr, "%s is not in the file\n", del_str);
return 0;
}
Exactly as Micheal said. On a file you can do only write and read operation. So you must read the char and when you find the exact word that you don't want to write, just don't write it. Otherwise you write it :)