3

I am reading a file line by line and splitting the string into tokens.

int main()
{
    FILE* fp;
    char  line[255];

    fp = fopen("file.txt" , "r");
    while (fgets(line, sizeof(line), fp) != NULL)
    {   
        char val1[16];
        char val2[9];

        strcpy(val1, strtok(line, ","));
        strcpy(val2, strtok(NULL, ","));

        printf("%s|%s\n", val1, val2);          
    }
}

My input file content (file.txt)

182930101222, KLA1512
182930101223, KLA1513
182930101224, KLA1514
182930101225, KLA1515

When I print get

 | KLA1512

Instead of

182930101222| KLA1512

What is the issue ?

kyle k
  • 5,134
  • 10
  • 31
  • 45

2 Answers2

6

Your problem (again) is that you're not allocating enough space for an array, and overwriting the end of it. The irony is that in this case, you don't even need to allocate any (additional) arrays. strtok() is tokenizing the line[] array, overwriting the delimiters with '\0' chars, and those are sufficient for your needs.

int main()
{
    FILE* fp;
    char  line[255];

    fp = fopen("file.txt" , "r");
    while (fgets(line, sizeof(line), fp) != NULL)
    {
        const char* val1 = strtok(line, ",");
        const char* val2 = strtok(NULL, ",");

        printf("%s|%s\n", val1, val2);
    }
}
phonetagger
  • 7,701
  • 3
  • 31
  • 55
  • can you how to remove newline and whitespace from char array in c. –  Aug 25 '13 at 13:27
  • @user2684719 - Removing _leading_ and _trailing_ whitespace from a modifiable `char` buffer is not difficult at all. I could write the function & post it for you, but how would that help you learn? Your `line[255]` buffer is modifiable by you in whatever way you see fit. You're already modifying it by calling `strtok()` on it (overwriting the `','` delimiters with nul characters (`'\0'`) which turns the buffer into separate C-style strings (which you keep track of with pointers `val1` and `val2`). Now, just write a new function of your own to remove leading & trailing whitespace.... – phonetagger Aug 25 '13 at 18:16
  • A suitable function signature would be: `char* remove_whitespace(char* str)`. With that function signature, you take a C-style string pointer, the function modifies the string as necessary, and returns a pointer to the same string with whitespace removed. If there is no leading whitespace, it'll just return the same pointer address that was passed to it. In the function, you loop from the start until the first non-whitespace character (see `isspace()`). When you find it, that's the new start of the string (which you need to keep track of in a pointer, because that's the pointer to return.) – phonetagger Aug 25 '13 at 18:22
  • Then keep looping until you find the end of the string (i.e. until you encounter the terminating `'\0'` character). Then scan _backwards_ until you find the first non-whitespace character, _or_ you find the start pointer address (either way). When you find it, simply write `'\0'` to the address one greater than that, which terminates the string at that point (truncating any whitespace, which includes any newline chars). – phonetagger Aug 25 '13 at 18:26
  • @user2684719 - BTW, if you found an answer on this page to be useful, please select it as "the best" answer. That's how you "pay" people for helping you. Also optionally up-vote any answers that were helpful even if you didn't select them as "the best" answer. – phonetagger Aug 25 '13 at 18:28
0

fgets inserts a newline

simply increase val2 size by 1 i.e. val2[10]

or remove trailing '\n'

while( fgets(line, sizeof(line), fp) != NULL ){ 
        char val1[16] ,val2[9];
        char *pos;
        if ((pos=strchr(line, '\n')) != NULL)
            *pos = '\0';
        strcpy(val1 , strtok(line,","));
        strcpy(val2 , strtok(NULL,","));
        printf("%s|%s\n",val1, val2);           
}
P0W
  • 46,614
  • 9
  • 72
  • 119