0

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);}
Lee Alex
  • 171
  • 2
  • 3
  • 13
  • 1
    You haven't shown enough code for us to know what type `d` is, but you said `int` in your question. If you're using `atof()` and expecting to get an `int`, that's at least one of your problems. PS: For more/better answers, include more of your code in your question. A small compile-able example would be a good starting point, along with some input that demonstrates the problem. – Caleb Dec 16 '20 at 22:08
  • @Caleb I try int and double, but same only a few work. – Lee Alex Dec 16 '20 at 22:11
  • 4
    Please provide a [complete minimal verifiable example](https://stackoverflow.com/help/minimal-reproducible-example). That is, complete code that anyone can run exactly as shown to reproduce the example. – kaylum Dec 16 '20 at 22:12
  • 1
    ... including some sample input, especially examples that fail where you think they should succeed. – John Bollinger Dec 16 '20 at 22:13

1 Answers1

1

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';
Lev M.
  • 6,088
  • 1
  • 10
  • 23
  • I try to add buf[reading] = '\0'; to the front after i = strlen(buf);, and I also try to add that in bottom, but result is same – Lee Alex Dec 16 '20 at 22:56
  • 1
    @LeeAlex you must add it before ` i = strlen(buf);` otherwise `strlen` will not work correctly. Also, you don't really need `strlen` because you have `reading` that gives you the length of the string. – Lev M. Dec 16 '20 at 23:35