Thread: char Handling, probably typical newbie stuff

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    6

    char Handling, probably typical newbie stuff

    Hello there,
    first of all, great Forum here. Already helped me alot up until now. However, there is one thing right now I can't seem to figure out, which is why I decided to make my first post here.

    Well, the Problem is probably due to the fact that I'm quite new to C programming. Up until now, I only had a little bit of C++ experience and now, I really do miss those strings...

    As far as I found out, strings do not exist in C, therefore I have been trying to use char[]. Now, basically that worked for me, but there's something strange.

    I tried to create a Program that would read a GPS String from a UART (it's something for an ATmega128 based Board). For that, I would read every single character into a char Variable and then strncat that into a char[]. In theory, it works up to the point where the first string is completely send and I want to start a second.

    First of all, here's the important part of the code:

    Code:
    char gpsGPRMC[7]="$GPRMC";
    char gpsHeader[7];
    char fromUART[2];
    char	s0[100];
    
    fromUART[1]='\0';
    
    if ( UART1_IsCharAvailable() ) { 
    	fromUART[0]= UART1_GetChar();
    	strncat(s0, fromUART, 1);	
    	fprintf(u0, "String Length: '%d' - Size: '%d' \n", strlen(s0), sizeof(s0));
    	if (fromUART[0]=='\n') {
    		fprintf(u0, "\n %s \n",s0);
    		s0[0]='\0';
            }
    }
    Now, there are a few things wrong with this (I think). You can see that I already print out the String Length and it's size...

    The String I send is: $GPRMC,142430.031,A,4936.8213,N,00611.9255,E,58.17 ,240.09,170609,,*31

    The Characters are well received and put in the fromUART Variable. I once did a fprintf of that to check, all worked well. They then get concatenated into the s0 Variable. That seems to work reasonably well the first time. Then I try to empty the "string" with setting the first byte to '\0' and start all over again. However, this "emptying" does not seem to work. At least, he seems to keep a few things from the content, thus leading to a corrupted String. And, furthermore, after two cycles, the program seems to stop. Since it's running on the ATmega128, I don't really get any precise feedback, but I suppose it's the s0 variable that grows way too big. That's why I did the printout of Size and Length. And indeed, I get something like this:

    String Length: '206' - Size: '100'
    String Length: '207' - Size: '100'
    String Length: '208' - Size: '100'
    String Length: '209' - Size: '100'
    String Length: '210' - Size: '100'
    String Length: '211' - Size: '100'
    String Length: '212' - Size: '100'
    String Length: '213' - Size: '100'
    String Length: '214' - Size: '100'
    String Length: '215' - Size: '100'
    String Length: '216' - Size: '100'
    String Length: '217' - Size: '100'
    String Length: '218' - Size: '100'
    String Length: '219' - Size: '100'
    String Length: '220' - Size: '100'
    String Length: '221' - Size: '100'
    String Length: '-4129' - Size: '100'
    String Length: '-35526116450z' - Size: '100'
    String Length: '-52481762740F' - Size: '100'
    String Length: '-35526116450z' - Size: '100'
    String Length: '-41985410275p' - Size: '100'
    String Length: '-46022468915P' - Size: '100'
    String Length: '-41177998547' - Size: '100'

    etc, etc...

    And the String itself is somewhat corrupted.

    I then changed things to

    Code:
    char *s0="";
    Which gave me an output of:

    String Length: '1' - Size: '2'
    String Length: '1' - Size: '2'
    String Length: '1' - Size: '2'
    String Length: '1' - Size: '2'
    String Length: '1' - Size: '2'

    ...

    Which is ... wrong... too.

    So I'm kinda lost here. What in the World do I to terribly wrong? Anyone got an Idea? Or can put me on the right path?

    Thanks already!!

  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
    Well your s0 array starts off containing garbage.

    char s0[100] = "";
    would fill it with zeros, and be the best thing to do for the moment.
    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
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    The next time do memset s0 to zero.

  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
    The "" string assignment does just that, with no possibility of messing it up.
    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
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    I meant the second time you want to reset s0.

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Salem View Post
    The "" string assignment does just that, with no possibility of messing it up.
    I thought that just sets the first character to '\0'?
    I know that this will set all the chars to '\0':
    Code:
    char s0[100] = {0};
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cpjust
    I thought that just sets the first character to '\0'?
    No, it does the same thing as in your example.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Jun 2009
    Posts
    6
    Hey,

    great... That already solved it. The problem with the second variant was apparently more Atmel-ringbuffer based. But that one got solved too. I told you, newbie stuff. Probably pure blindness from my part in this case.
    However, I have one more question. Before opening a new Thread, I suppose I could just post that one here too...Again, my GPS String. As it contains Longitude and Latitude, I have to convert these from String to Float at some point.
    Now, I succeed in slicing the String using strtok. This gives me the Numbers in String form. I then try to convert them using things like this:

    Code:
    char *gpsLatitudeString;	
    float gpsLatitude;
    
    if(EOF == sscanf(gpsLatitudeString, "%f", &gpsLatitude)) {
      			fprintf(u0, "\nError in Latitude String to Float Conversion\n");
    		}
    Note that gpsLatitudeString does indeed contain the correct value, something like 1234.5678
    Also, I do not get the Error Message I defined here, so this *should* work. Unfortunately, gpsLatitude is empty afterwards. I tried changing it to:

    Code:
    char *gpsLatitudeString;	
    float *gpsLatitude;
    
    if(EOF == sscanf(gpsLatitudeString, "%f", gpsLatitude)) {
      			fprintf(u0, "\nError in Latitude String to Float Conversion\n");
    		}
    But this breaks the rest of my Program as I want to do some calculations with these Values later on and that supposedly doesn't work with *float. Or, as usual, I wouldn't know how.

    So, once again, I'm stuck for some time with this too... :/
    Last edited by Neolyth; 06-18-2009 at 11:55 AM.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    char *gpsLatitudeString;
    float *gpsLatitude;
    Neither of these POINT to any useful memory.
    You're reading from one garbage location, and writing to another.

    You need to think about what a function like sscanf is trying to do, and that involves more than just declaring variables with the right type.
    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.

  10. #10
    Registered User
    Join Date
    Jun 2009
    Posts
    6
    So, slept over it
    Well, of course, you're right. So, let me show you how things are right now:

    Code:
    char gpsLatitudeString[20];	
    float gpsLatitude;
    char *pointer;
    
    [...]
    pointer=strtok(inputString,",");
    strcpy(gpsLatitudeString,pointer);
    [...]
    
    fprintf(u0, "\n gpsLatitudeString: %s", gpsLatitudeString);
    
    if(EOF == sscanf(gpsLatitudeString, "%f", gpsLatitude)) {
      			fprintf(u0, "\nError in Latitude String to Float Conversion\n");
    		}
    
    fprintf(u0, "\n gpsLatitude: %f", gpsLatitude);
    So, I get a gpsLatitudeString of, ie, 5112.4041
    Alas, after the conversion with sscanf, gpsLatitude still contains "0.000000"
    If I do the sscanf conversion as %s to a char[], the Variable contains the correct Value. So I suppose that my approach to sscanf is correct, it's just something with the floating point that I'm missing?

    I know, probably easy here, but I've been searching for a few hours now and this is the best I can get.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Don't forget the ampersand!
    Code:
    if(EOF == sscanf(gpsLatitudeString, "%f", &gpsLatitude)) {
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    Registered User
    Join Date
    Jun 2009
    Posts
    6
    Yes, true. I omit it for the use of char[], but well...
    Even when using the ampersand, the result still is 0.000000

    Well, I tried something. When I do this:

    Code:
    int j;
    int k;
    char test[]="1234";
    
    j=sscanf(test, "%i", &k);
    Then k contains 1234 as an int and j contains 1, proving that sscanf did it's work correctly.

    When I do
    Code:
    int j;
    float k;
    char test[]="1234";
    
    j=sscanf(test, "%f", &k);
    Then k contains 0.000000 and j contains 0, proving that sscanf did not detect a Number there. So I suppose there's somehting wrong with %f?

  13. #13
    Registered User
    Join Date
    Jun 2009
    Posts
    6
    Ok,
    well I did some research and found atof() as another possibility for me. Altough I would love to simply use sscanf to parse the entire String at one, I now keep using strtok() to decompose the String into its individual parts and the use atof to convert the Number Strings to Float.

    So, altough this works now, I would still be very happy if anyone had an idea why sscanf(a,"%f",&b) won't work.

    Nonetheless, a big thanks already for all your posts!

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Neolyth View Post
    Yes, true. I omit it for the use of char[], but well...
    Even when using the ampersand, the result still is 0.000000

    Well, I tried something. When I do this:

    Code:
    int j;
    int k;
    char test[]="1234";
    
    j=sscanf(test, "%i", &k);
    Then k contains 1234 as an int and j contains 1, proving that sscanf did it's work correctly.

    When I do
    Code:
    int j;
    float k;
    char test[]="1234";
    
    j=sscanf(test, "%f", &k);
    Then k contains 0.000000 and j contains 0, proving that sscanf did not detect a Number there. So I suppose there's somehting wrong with %f?
    If I compile that code on my machine I get "j=1 k=1234.000000", so there's nothing wrong with the code (at least the part that's posted).

  15. #15
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    It's quite strange that %f doesn't seem to be working for you. Out of curiousity, do you get the same output that I do here?
    Code:
    $ cat scanff.c
    #include <stdio.h>
    
    int main() {
        float f;
        double d;
        int n;
    
        n = sscanf("3.14", "%f", &f);
        printf("n=%d, float f=%f\n", n, f);
    
        n = sscanf("3.14", "%lf", &d);
        printf("n=%d, double d=%f\n", n, d);
    
        return 0;
    }
    $ ./scanff
    n=1, float f=3.140000
    n=1, double d=3.140000
    $
    Because if you don't, I'd say it's a bug with your runtime environment. What about ordinary scanf()? Does it read floats with %f properly?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. C++ ini file reader problems
    By guitarist809 in forum C++ Programming
    Replies: 7
    Last Post: 09-04-2008, 06:02 AM
  3. Program Crashing
    By Pressure in forum C Programming
    Replies: 3
    Last Post: 04-18-2005, 10:28 PM
  4. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  5. Strings are V important...
    By NANO in forum C++ Programming
    Replies: 15
    Last Post: 04-14-2002, 11:57 AM