Using loop to and atof to make more then ten thousands str to be double, but only a few work in C program

91 views Asked by At

Below code is a C code, t is a string from a txt document, there are 10000+ strings here, like what I print in the code printf("%s\n", t);, I can see many str. However, when I use atof to make t become int, there is only 72 str become double, does anyone know what is wrong?

int f;
char buf[BUFSIZ], *p, *t;
struct dataset *s;
double d;
int line;
int i;
int reading;


if (n == NULL) // n is a number from global
{
    f = STDIN_FILENO;
    n = "<stdin>";
}
else if (!strcmp(n, "-"))
{
    f = STDIN_FILENO;
    n = "<stdin>";
}
else
{
    f = open(n, O_RDWR);
}
if (f == -1)
    err(1, "Cannot open %s", n);

s = NewSet();
s->name = strdup(n);


while ((reading = read(f, buf, sizeof(buf) - 1)) > 0)
{
    

    i = strlen(buf);


    char *ptr = strdup(buf); //duplicate of pointed to by buf
    char *ptr_copy = ptr;    //copy ptr, let strsep work on  prt_copy
    for (i = 1, t = strsep(&ptr_copy, delim);
         t != NULL && *t != '#';
         i++, t = strsep(&ptr_copy, delim))
    {

        if (i == column)
            break;
    }

    if (t == NULL || *t == '#')
        continue;

    printf("%s\n", t);

    d = atof(t);

        printf("%f\n", d);
         free(ptr);}
1

There are 1 answers

2
Lev M. On

Your program is failing because you do not null terminate the strings read from file.

read(f, buf, sizeof(buf) - 1)

This reads raw bytes from file and stores them in buf with no manipulation.

It will not add \0 to the end of the read input.

After that, both:

i = strlen(buf);

and

strdup(buf);

will give unpredictable results, most likely counting and copying garbage at the end of your string.

And there is no telling how long this loop will run for each line in your file:

for (i = 1, t = strsep(&ptr_copy, delim);
     t != NULL && *t != '#';
     i++, t = strsep(&ptr_copy, delim))

So, even without seeing your input or complete code, it looks like you need to start by wrapping your file handle in FILE* object and using fgets, or null terminate the result of read your self, like this:

buf[reading] = '\0';