0

I want to do the following:

  • open and read and ASCII file

  • locate a substring (geographical coordinates)

  • create its replacement (apply corrections to the original coordinates)
  • overwrite the original substring (write in the original file the corrected coordinates).

The format of the ASCII file is: $GPGGA,091306.00,4548.17420,N,00905.47990,E,1,09,0.87,233.5,M,47.2,M,,*53

I will paste here only the part of the code that is responsible for this operation:

opnmea = fopen (argv[1], "r+");
if (fgets(row_nmea, ROW, opnmea)==NULL){             
   if (strstr(row_nmea,"$GPGGA")!=NULL) {
       sscanf(row_nmea+17, "%10c", old_phi);
       sscanf(row_nmea+30, "%11c", old_lam);
       sscanf(row_nmea+54, "%5c", old_h);
       fputs();
   }
}

What I do till now is to extract in a variable the old coordinates and I was thinking to use fputs() for overwriting the old with new values. But I could not do it. The other part of the code that is not here is computing the correct coordinates. My idea is to correct the rows one by one, as the fgets() function reads each line.

I would appreciate very much any suggestion that can show me how to use fputs() or another function to complete my work. I am looking for something simple as I am beginner with C.

Thank you in advance.

2
  • 2
    If this is something you want to do rather than e.g. a homework assignment -- something like Python is a much more natural choice, especially if you are a beginner in C Commented Nov 23, 2015 at 14:47
  • 1
    if (fgets(row_nmea, ROW, opnmea)==NULL){ : == typo as !=. Commented Nov 23, 2015 at 14:48

2 Answers 2

2

Patching a text file in place is not a good solution for this problem, for multiple reasons:

  • the modified version might have a different length, hence patching cannot be done in place.

  • the read-write operation of standard streams is not so easy to handle correctly and defeats the buffering mechanism.

  • if you encounter an error during the patching phase, a partially modified file can be considered corrupted as one cannot tell which coordinates have been modified and which have not.

  • other programs might be reading from the same file as you are writing it. They will read invalid or inconsistent data.

I strongly recommend to write a program that reads the original file and writes a modified version to a different output file.

For this you need to:

  • open the original file for reading opnmea = fopen(argv[1], "r");

  • open the output file for writing: outfile = fopen(temporary_file_name, "w");

  • copy the lines that do not require modification: just call fputs(row_nmea, outfile).

  • parse relevant data in lines that require modification with whatever method you are comfortable with: sscanf, strtok, ...

  • compute the modified fields and write the modified line to outfile with fprintf.

Once the file has been completely and correctly handled, you can replace the original file with rename. The rename operation is usually atomic at the file-system level, so other programs will either finish reading from the previous version or open the new version.

Of course, if the file has only one line, you could simply rewind the stream and write back the line with fprintf, but this is a special case and it will fail if the new version is shorter than the original. Truncating the extra data is not easy. An alternative is to reopen the file in write mode ("w") before writing the modified line.

Sign up to request clarification or add additional context in comments.

2 Comments

The file has many, many lines, one for each second of coordinates acuqisition. thank you very much for your step-by-step guidance. I will try to follow your recommendations.
thank you for the help, I followed your guidelines and it works. I used sscanf and %[^,] to break the fields of the string and then with I used frpintf to build the new string with corrected coordinates. Thank you!
1

I would recommend strtok(), followed by your revision, followed by strcat().

strtok() will let you separate the line using the comma as a delimiter, so you will get the field you want reliably. You can break up the line into separate strings, revise the coordinates you wish, and reassemble the line, including the commas, with strcat().

These pages include nice usage examples, too:

http://www.cplusplus.com/reference/cstring/strtok/ http://www.cplusplus.com/reference/cstring/strcat/?kw=strcat

4 Comments

I will try it. Thank you!
I fail to see how this answers the question. The OP wants to know how to write the modified string back to the file.
@chqrlie, While the post details things, including reading and writing the file, the title focuses on substring replacement. My answer addresses that pretty directly. I hope that helps.
What you propose is breaking down the original string in chunks with strtok and composing a new string with strcat. That's a solution indeed, but the OP might mistakenly use strcat to patch the original string and fail to get that to work correctly for good reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.