Thread: How to split up CAN data line

  1. #1
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154

    How to split up CAN data line

    Hi,

    I'm sure there must be a very simple solution for this, but i don't now the right C functions to do it. Therefore I hope someone can help me out with this.
    I'm working with CAN (Controller Area Network) data and I've got strings returned, like these:

    Code:
       0.7746 1  861             Rx   d 8  16   3  32   0   0 255  80   0
       0.7821 1  861             Rx   d 8  16   3  32   0   0   0  80   0
    The exact meaning of the data is not important I think. I'll use one as an example though.
    The first value of the line (0.7746 and 0.7821) is the time of the CAN message in ms. Now what I need to do is categorise the data seperately. So I want an array to be filled with those times e.g. time_array(0.7746,0.7821,...). And so on... I need to do this with all the values in the lines above, another example: identifier_array(861,861,...).
    Again, I'm sure there's a function that can seperate the values (with the space as a "separate-parameter") like explode in php but I don't know how to do this in C.

    Could anyone point me to an example or help me out some way please?

    Thanks in advance, René
    Last edited by rkooij; 03-13-2006 at 09:26 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Use sscanf()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154
    Thanks for the answer Salem. I'm sorry I can't find any information on how to apply the sscanf function in my code.

    Now I've been trying all day with various methods and it's starting to <........> me off.

    I really hope there's someone able and willing to help.

    I've got the following piece of code...

    Code:
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <strings.h>
    #include <windows.h>
    
    int main(void)
    {
        FILE *file_pointer_in, *file_pointer_out;
        char file_in[256],file_out[256], buf[BUFSIZ];
        int ih, cnt=0;
        bool space_flag=FALSE, skip_flag=FALSE;
    	
        printf("Please enter source file name: ");
        scanf("%s",file_in);
    	
        if((file_pointer_in = fopen(file_in, "rb"))== NULL)
        {
        printf("Can't open source file\n");
        getch();
        return 1;
        }
    
        printf("Please enter destination filename: ");
        scanf("%s",file_out);
        file_pointer_out = fopen(file_out,"wb");
        while((ih=fgetc(file_pointer_in))!=EOF)
        {
           while(skip_flag==FALSE)
           {
              while(cnt<3)
              {
                 while((ih=fgetc(file_pointer_in))=='\n')
                 { skip_flag=TRUE; cnt++; }
              }
           }
           
           while((ih=fgetc(file_pointer_in))!=EOF)
                  
                 if(ih==' '){ space_flag=TRUE; }
                 else
                 {
                    fputc(ih,file_pointer_out);
                    putch(ih);
                    
                    if(space_flag)
                    {
                       space_flag=FALSE;
                    }
                 }
    
           }
    	
        fclose(file_pointer_in);
        fclose(file_pointer_out);
        getch();
        return 0;
    }
    Now what I want to do is read the input file line by line and save the data like I said in my first post. An input file would be like the one attached to this post.
    Please note this code deletes the spaces from the input file. That's just a test for myself to see if I was able to manipulate the file, so that's where the function I just described should be placed.

    Any help would be highly appreciated. Thanks very much in advance!
    http://www.f1rstracing.nl/
    OS: Windows XP
    Compiler: Dev-C++

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    1. It's a text file, so only use "r" and "w".

    2. Use fgets to read a whole line. The archetype read a file a line at a time is
    Code:
    FILE *fp = fopen( "file.txt", "r" );
    char buff[BUFSIZ];
    while ( fgets ( buff, BUFSIZ, fp ) != NULL ) {
      // do stuff with buff
    }
    > 0.7821 1 861 Rx d 8 16 3 32 0 0 0 80 0
    Say for example, you wanted the first parameter as a string, skip the 2nd and the 3rd as an int
    Code:
    char p1[100];  // param1
    int p3;  // param3
    if ( sscanf( buff, "%s %*d %d", p1, &p3 ) == 2 ) {
      // success
    }
    %*d means read an integer, but DON'T assign it to a result variable. It's useful for skipping over bits of a line you're not interested in.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154
    Quote Originally Posted by Salem
    // do stuff with buff
    ^^

    Thanks so much for your answer, I'm on it.
    Last edited by rkooij; 03-14-2006 at 09:48 AM.
    http://www.f1rstracing.nl/
    OS: Windows XP
    Compiler: Dev-C++

  6. #6
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154
    Salem, thanks so much... finally Ive almost got the result I wanted!
    There's one extra step that's different from your example. I want to store the values in an array.
    Code:
              if ( sscanf( buf, "%s %*d %d", p1, &p3 ) == 2 ) {
                 time_array[counter]=p1;
                 identifier_array[counter]=p3;
    The identifier array works nicely, though for some reason I can't store p1 in the time_array. It results in the next error message:
    46 scanfile2.cpp cannot convert `float[100]' to `float' in assignment
    I also see you said I need to store p1 as a string, though I need to compare the time values later on. Therefore I think it would be better to store the value as a float value?

    Thanks again, René
    http://www.f1rstracing.nl/
    OS: Windows XP
    Compiler: Dev-C++

  7. #7
    1ST » R. vd Kooij
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    154
    Nevermind, got it working! Thanks!
    http://www.f1rstracing.nl/
    OS: Windows XP
    Compiler: Dev-C++

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sending data - line by line?
    By tuckker in forum C Programming
    Replies: 0
    Last Post: 02-21-2009, 09:31 PM
  2. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  3. How to enter a line of data in C?
    By advancedk in forum C Programming
    Replies: 2
    Last Post: 07-30-2008, 02:29 PM
  4. [question]Analyzing data in a two-dimensional array
    By burbose in forum C Programming
    Replies: 2
    Last Post: 06-13-2005, 07:31 AM
  5. Validating the contents of a char buffer
    By mattz in forum C Programming
    Replies: 3
    Last Post: 12-09-2001, 06:21 PM