[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 241
  • Last Modified:

Open a file and replace a string

Hi,

I know nothing about C, and need to write a small script using it. Basically I need to find a file on a machine (TNSNames.ora) and replace one of the entries in it. A bit of handling should be done if the file isn't in the C:\orawin95\net80\admin directory, or if the search text is not found.

I don't want to learn C, so if someone could write the correct code for me, it would be most appreciated.

Thanks, Nik.
0
NikWhitfield
Asked:
NikWhitfield
  • 8
  • 6
  • 2
  • +2
1 Solution
 
marcjbCommented:
/*
Not the most efficient method, but it should work.  The file is opened, and so is a temp file.  All lines that don't match the string to be replaced are copied to the temp file, and then they are copied back.  The temp file is automatically removed when closed.
This is ANSI C, so you should have no trouble compiling.  One thing to note is that the string compare function is case sensitive.  
Hope this helps.
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define   MAX   1024

int main()
{
FILE *f;
FILE *tmp;
char aLine[MAX];
char toReplace[MAX];
int found = 0;

/* Try and open the file */
if ( (f = fopen("C:\\orawin95\\net80\\admin\\TNSNames.ora", "r")) == NULL )
    {
    printf("\nERROR: Failure to open file TNSNames.ora\n");
    exit(EXIT_FAILURE);
    }

/* Open a temporary file */
if ( (tmp = tmpfile()) == NULL )
    {
    printf("\nERROR: Failure to open temp file\n");
    exit(EXIT_FAILURE);
    }

/* Get the string to replace (This could be done many ways) */
printf("\nEnter the string to replace\n");
fgets(toReplace, MAX, stdin);  /* Keep the newline */

/* Cycle through file to find string */
while ( fgets(aLine, MAX, f) != NULL )
    {
    if ( strcmp(aLine, toReplace) == 0 )
      {
      found = 1;
      continue;
      }
    /* else, copy the line to a temp file */
    fprintf(tmp, "%s", aLine);
    }

/* Close TNS and go to beginning of temp file */
fclose(f);
rewind(tmp);

/* Re-open file to truncate data, and copy new data from temp file */
if ( (f = fopen("C:\\orawin95\\net80\\admin\\TNSNames.ora", "w")) == NULL )
    {
    printf("\nERROR: Failure to open file TNSNames.ora\n");
    exit(EXIT_FAILURE);
    }

while ( fgets(aLine, MAX, tmp) != NULL )
    fprintf(f, "%s", aLine);

if ( found == 0 )
    printf("\nString not found in file\n");
else
    printf("\nString found and removed\n");

fclose(f);
fclose(tmp);
return 0;
} /* main */
0
 
NikWhitfieldAuthor Commented:
I have run this code and it simply says "String not found in file", when I know that it is in the file.

Also, the user shouldn't have to input the phrase.

It can be hardwired as :

Find - "uk-finance-as01"
Replace with - "uk-lop-as01"

Another issue - the find phrase will be in amongst other text, so replacing lines is no good.
0
 
NikWhitfieldAuthor Commented:
I have run this code and it simply says "String not found in file", when I know that it is in the file.

Also, the user shouldn't have to input the phrase.

It can be hardwired as :

Find - "uk-finance-as01"
Replace with - "uk-lop-as01"

Another issue - the find phrase will be in amongst other text, so replacing lines is no good.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
marcjbCommented:
If you mean the following:
replace: get
string: together
result: toher

use the strstr function to determine one string is in another, and then shift the string over.

For example, assume that the string to replace is still in a variable called toReplace.
Also, delace a character pointer:
char *ptr;



/* Add this line if letting the user input the string to find, else, just hard code the string to replace */

strtok(toReplace, "\n"); /* Don't keep the newline */

/* CHANGE TO THE FOLLOWING */

/* Cycle through file to find string */
while ( fgets(aLine, MAX, f) != NULL )
    {
    if ( (ptr = strstr(aLine,toReplace)) != NULL )
      {
      /* substring found.  Now replace */
      memmove(ptr, ptr + strlen(toReplace),
            1 + strlen(ptr + strlen(toReplace)) );
      /* add 1 to grab the null terminator */
      found = 1;
      }
    fprintf(tmp, "%s", aLine);
    }

0
 
NikWhitfieldAuthor Commented:
No this is not what I mean. I want to do the equivalent of the VB 'Replace' command.

String to find: uk-finance-as01
Replace with : uk-lop-as01
File : "(stuff,(uk-finance-as01),)"

Result : "(stuff,(uk-lop-as01),)"
0
 
marcjbCommented:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define   MAX   1024

int main()
{
FILE *f;
FILE *tmp;
char aLine[MAX];
char line2[MAX];
int found = 0;
char *ptr;
char toFind[] = "uk-finance-as01";
char toReplace[] = "uk-lop-as01";

/* Try and open the file */
if ( (f = fopen("C:\\orawin95\\net80\\admin\\TNSNames.ora", "r")) == NULL )
    {
    printf("\nERROR: Failure to open file TNSNames.ora\n");
    exit(EXIT_FAILURE);
    }

/* Open a temporary file */
if ( (tmp = tmpfile()) == NULL )
    {
    printf("\nERROR: Failure to open temp file\n");
    exit(EXIT_FAILURE);
    }

/* Cycle through file to find string */
while ( fgets(aLine, MAX, f) != NULL )
    {
    if ( (ptr = strstr(aLine,toFind)) != NULL )
      {
      strcpy(line2, ptr + strlen(toFind));
      *ptr = 0;
      strcat(aLine, toReplace);
      strcat(aLine, line2);
      found = 1;
      }
    fprintf(tmp, "%s", aLine);
    }
fclose(f);
rewind(tmp);

/* Re-open file to truncate data, and copy new data from temp file */
if ( (f = fopen("C:\\orawin95\\net80\\admin\\TNSNames.ora", "w")) == NULL )
    {
    printf("\nERROR: Failure to open file TNSNames.ora\n");
    exit(EXIT_FAILURE);
    }

while ( fgets(aLine, MAX, tmp) != NULL )
    fprintf(f, "%s", aLine);

if ( found == 0 )
    printf("\nString not found in file\n");
else
    printf("\nString found and removed\n");
return 0;
} /* main */
0
 
NikWhitfieldAuthor Commented:
Much better!

One last refinment though (I'll add extra points for the new requirements!).

I just need it to display a success or failure MessageBox.

i.e. If the text is changed OK, then show a messagebox saying something like "File updated successfully".
And if it fails for any reason (e.g. if the file is not found), then messagebox "File update failed. Please phone OM support."

Cheers!
0
 
marcjbCommented:
Sorry, but I'm not familier with the Windows API, so I don't know how to do messages boxes.  
0
 
MaxItnCommented:
Header file: Winuser.h
Windows CE versions: 1.0 and later


Syntax
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,
UINT uType);

Parameters
hWnd

[in] Handle to the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.

lpText

[in] Long pointer to a null-terminated string that contains the message to be displayed.

lpCaption

[in] Long pointer to a null-terminated string used for the dialog box title. If this parameter is NULL, the default title “Error” is used.

uType

[in] Specifies a set of bit flags that determine the contents and behavior of the dialog box. This parameter can be a combination of flags from the following groups of flags.




You can find different types of msgboxes in the help of msdn. this is selected from the last parameter.
0
 
X2Commented:
Does this need to be in C?
Can it be C++?  If so, I'll look into
converting marcjb's code into a short
MFC program (i'm still learning MFC,
so this can be practice for me).  I
think marcjb spent some good time
writing that program and would like to
see him getting the points.
0
 
marcjbCommented:
Thank you x2 :)

Nik,
When I was copying the source over I forgot to include the following two lines before the return that ends the program.


fclose(f);
fclose(tmp);


They aren't really needed as the program ending should automatically close the files, but it is good practice.
0
 
ahoffmannCommented:
does this need to be C, C++ or what ever?
When most other tools may do this job in a single, simple line, like
    sed -e 's/uk-finance-as01/uk-lop-as01/g' TNSNames.ora > newfile
or
  perl -i -pe  's/uk-finance-as01/uk-lop-as01/g' TNSNames.ora
even NT's cmd.exe may do it in 2 or 3 lines.
0
 
NikWhitfieldAuthor Commented:
Any language is OK as long as I don't need to distribute Dlls or anything, just an executable.
0
 
NikWhitfieldAuthor Commented:
Any language is OK as long as I don't need to distribute Dlls or anything, just an executable. So C, C++ etc are fine.

ahoffman - what's sed?
0
 
NikWhitfieldAuthor Commented:
By the way, I have no idea why it's printing my comments twice!

An add on to my last comment - as long as no ditribution files are needed AND it notifies the user as to whether it was a success or failure are the 2 main requirements. I don't care how this is achieved. The platform will be Windows 95 / NT.
0
 
NikWhitfieldAuthor Commented:
Thanks for the work. I managed to implement the rest myself.
0
 
marcjbCommented:
Thank you, and good luck.
0
 
ahoffmannCommented:
sed is some of these tiny magic tools available on any UNIX, but ported to M$ world too
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 8
  • 6
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now