2

I am trying to write a general function that will read in parameters from formatted text file. I want it to be flexible enough that the parameter list can vary. What is the best way to accomplish this in C?

I've been struggling with this for a few days. The strings that I'm able to extract from the file are not what I expected. The sample text file I'm using to debug is simple:

Nx : 1600;
Ny : 400;
dx : .524584;
dy : .25;
dt : 1;

My program is below.

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

int main(int argc, char * argv[])
{
if(argc!=2)
{   
    printf("ERROR:  Usage: ./Practice3 <input file>");      
}
else
    {
FILE * fr = fopen(argv[1], "rt");


if(fr == NULL){printf("file %s not found", argv[1]);}

char * tmpstr1 ;
char * tmpstr2 ;

char * delimPtr;
char * endPtr;

int Nx = 0;
int Ny = 0;
double dx = 0;
double dy = 0;

    char tempbuff[100];

    while(!feof(fr)) 
    {
         if (fgets(tempbuff,100,fr)) {

            delimPtr = strstr(tempbuff,":");
            endPtr = strstr(delimPtr,";");
            strncpy(tmpstr1,tempbuff,delimPtr-tempbuff);
            strncpy(tmpstr2,delimPtr+2 ,endPtr-delimPtr-2);
            printf("<<%s>>\n",  tmpstr1);
            printf("<<%s>>\n",  tmpstr2);

            if (strcmp(tmpstr1,"Nx")==0) {
                 Nx = atoi(tmpstr2);
            } 
            else if (strcmp(tmpstr1,"Ny")==0) {
                 Ny = atoi(tmpstr2);
            }
            else if (strcmp(tmpstr1,"dx")==0) {
                 dx = atof(tmpstr2);
            }
            else if (strcmp(tmpstr1,"dy")==0) {
                 dy = atof(tmpstr2);
            }
            else{
                printf("Unrecongized parameter : \"%s\"\n", tmpstr1);
            }


         }


    }


    fclose(fr);

    printf("\nNx : %d \nNy : %d  \ndx : %f  \ndy : %f \n",  Nx,Ny,dx,dy);


}//end of code executed when input is correct 


}

I am compiling with gcc -std=c99. The tmpstr1 variable prints out with a weird blob character at the end. I can't reliably extract the parameter name the way I have it now. What is a better way?

Also, it seems that tmpstr2 doesn't get overwritten completely from strncpy so the numbers are getting mixed up. It seems like C is not designed to do this kind of sting manipulation easily. But I have to use C for class so I'm stuck. Any ideas?

8
  • 4
    You never actually allocate any memory for the tempstrs, so you have lots of undefined behavior going on. Commented Apr 12, 2014 at 23:07
  • 1
    Don't use feof() to check for end-of-file, check the return value of fgets() instead. Commented Apr 12, 2014 at 23:16
  • and strncpy(tmpstr1,tempbuff,delimPtr-tempbuff); includes space. and it is not considered for the null-terminator.、 Commented Apr 12, 2014 at 23:25
  • @BLUEPIXY: The same is true for tmpstr2, due to the ;-endPtr. Commented Apr 12, 2014 at 23:39
  • 1
    @user3527862: feof() returns true only after you've tried to read past the end of the file. This means your while-loop is executed one time too many. It doesn't hurt in this case, because you also check if(fgets(...)), but it's redundant and not checking what you think it is. Also, note the missing null-termination in your code. Commented Apr 12, 2014 at 23:48

2 Answers 2

2
char tmpstr1[16];
char tmpstr2[16];
...
/*
delimPtr = strstr(tempbuff,":");
endPtr = strstr(delimPtr,";");
strncpy(tmpstr1,tempbuff,delimPtr-tempbuff-1);
strncpy(tmpstr2,delimPtr+2 ,endPtr-delimPtr-2);
*/
sscanf(tempbuff, "%15s : %15[^;];", tmpstr1, tmpstr2);
Sign up to request clarification or add additional context in comments.

1 Comment

This was very helpful! I took out the ; at the end of lines of txt file with my parameters. This made the final code nicer -- sscanf(tempbuff, "%15s : %15s", tmpstr1, tmpstr2);
0

As pointed out by John3136, you don't allocate any memory for tempstr1 and tempstr2. You probably want to define them like tempbuf, as stack arrays.
Furthermore, you misuse strncpy():
a) The part of the strings you copy from is not null-terminated, so memcpy() would be equivalent in your case, which brings us to
b) You have no null-terminator. strncpy() does not add a null-terminator if it wasn't encountered within the number of chars it was told to copy. Thus, you need to put the null-terminator manually: tempstr[n] = '\0'

Comments

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.