Problems with C? Problems with strstr()!!??

Go To Last Post
31 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm at a loss. This is killing me.
Should be simple, but the output doesn't make sense:

char* vf = strstr(gsmBuffer, "+CMGR: \"REC UNREAD\",");
uartSendString("\r\n-----------------\r\n");
uartSendString(gsmBuffer);
uartSendString("\r\n-----------------\r\n");
uartSendString(vf);
uartSendString("\r\n-----------------\r\n");

RESULT:

-----------------

$$$$$$$$$$$$1

+CMGR: "REC UNREAD","30600073","","12/05/28,22:30:33-16"
From: xxxxxxxxxx
                caR ON

$$$$
-----------------

$$$$$$$$$$$$1

+CMGR: "REC UNREAD","30600073","","12/05/28,22:30:33-16"
From: 2263735694
                caR ON

$$$$
-----------------

How is that POSSIBLE????
uartSendString(vf) should just show

+CMGR: "REC UNREAD","30600073","","12/05/28,22:30:33-16"
From: 2263735694
                caR ON

$$$$

What am I missing here guys???

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From the reference:

Quote:

char * strstr(const char * s1,
const char * s2
)
The strstr() function returns a pointer to the beginning of the substring, or NULL if the substring is not found. If s2 points to a string of zero length, the function returns s1.

It seems to be returning a pointer to s1, so vf points to gsmBuffer.

Try using:

const char* s2 = "+CMGR: \"REC UNREAD\",";
char* vf;

vf = strstr(gsmBuffer,s2);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is the string constant located in RAM ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This test program works as expected for me:

#include 
#include 


int main(void)
{
    char gsmBuffer[] = "\n\
$$$$$$$$$$$$1\n\
\n\
+CMGR: \"REC UNREAD\",\"30600073\",\"\",\"12/05/28,22:30:33-16\"\n\
From: xxxxxxxxxx\n\
                caR ON\n\
\n\
$$$$";
    
    char *vf = strstr(gsmBuffer, "+CMGR: \"REC UNREAD\",");
    
    puts("----------------");
    puts(gsmBuffer);
    puts("----------------");
    puts(vf);
    puts("----------------");

    return 0;
}

both with gcc in Ubuntu and with avr-gcc if I add usart initialization.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EDIT: This is the declaration:
(global)
char gsmBuffer[512];
const char* pGsmBuffer = gsmBuffer;

Alright...
I've since change my code a bit in hopes of resolving this problem. But now I'm here, and it really doesnt make sense AT ALL:


	char* p = 0;

	p = strstr(pGsmBuffer, "+CMGR: \"REC UNREAD\",");
	
	uartPrintNum(pGsmBuffer, 'd');
	uartPrintNum(p, 'd');
	
	uartSendString("\r\n4----------------------\r\n");
	uartSendString(p);
	uartSendString("\r\n4----------------------\r\n");
	
	q = strstr(pGsmBuffer, "From: 5555555555");
	uartSendString("\r\n5----------------------\r\n");
	uartSendString(q);
	uartSendString("\r\n5----------------------\r\n");

Output:

985 985
4----------------------

$$$$$$$$$$$$1

+CMGR: "REC UNREAD","66666666","","12/06/03,13:30:04-16"
From: 5555555555
                car ON

$$$$
4----------------------

5----------------------
From: 5555555555
                car ON

$$$$
5----------------------

So we see, that it finds the string in "p", because it does not return a null pointer. but instead it returns the pointer to the start of the searched string!
but THEN, I search in the same string for a different sub string, and it works perfectly.

PLEASE does anyone have any ideas??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely that says the first pattern to match is not found in the string? Perhaps try looking for something simpler to start with:

 p = strstr(pGsmBuffer, "+CMGR");

does that work? If so then do a binary split between what doesn't work and what does work until you find the culprit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Normally I would agree - it must not be working. But:

Quote:

The strstr() function returns a pointer to the beginning of the substring, or NULL if the substring is not found.

I'll try what you suggested now and I'll be right back!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Its the comma!
Whats up with that?? How do I get around that? I tried "\,", but that did nothing as I do believe thats not even an escape sequence.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Convert the content of the string into numbers and send them via the UART. This way you can check what the string actually contains. Perhaps the terminal program shows you the comma in place of an unprintable character or there is additional content around the comma not shown by the terminal program or ...

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

er... actually its random.
it started screwing up again, and now i just search for "+CMGR", and its again returning the pointer to the start of the string.

What the hell is happening. I'm so lost.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK. I think i have the problem. I just have no idea at this point WHY.

Quote part two to the description of the strstr() function is: If s2 points to a string of zero length, the function returns s1.

p = strstr(pGsmBuffer, "+CMGR: \"REC UNREAD\",");

So HOW is it possible that "+CMGR: \"REC UNREAD\"," is a string of zero length?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Alright. Perhaps someone might get some ideas from this:

WHY IS pSearch NOT GETTING MY STRING????????????????????????

	char search[100] = {0};
	const char* pSearch = search;

strcpy(pSearch,"CMGR: \"REC UNREAD\",");

	uartSendString("\r\n3----------------------\r\n");
	uartSendString(pSearch);
	uartSendString("\r\n3----------------------\r\n");
	
	p = strstr(pGsmBuffer, pSearch);
	uartSendString("\r\n4----------------------\r\n");
	uartSendString(p);
	uartSendString("\r\n4----------------------\r\n");

OUTPUT:

3----------------------


3----------------------

4----------------------

$$$$$$$$$$$$1

+CMGR: "REC UNREAD","66666666","","12/06/03,15:02:23-16"
From: 5555555555
                car on

$$$$
4----------------------
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You make no attempt to test p or q for NULL.
uartSendstring(p) will simply output whatever starts at address 0.

I seem to remember a problem with strstr() in an early release of WinAvr.

So the obvious first step is to create a test suite. e.g. put a known string in pGsmBuffer.
1. test for a known match
2. test for a known fail.
3. test for empty strings, start of string, end of string, strings containing commas, newlines, ...

If any of your tests fail, you can present the test suite for others to comment. After all it is not unknown for library bugs. It is certainly not unknown for Atmel to introduce 'features' with their Toolchain.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

tkurowski wrote:

	char search[100] = {0};
	const char* pSearch = search;

strcpy(pSearch,"CMGR: \"REC UNREAD\",");


I don't see how that even compiles - you're not supposed to be allowed to copy into a const char *.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.p
I essentially did what you are describing.
I believe I found a bug with the strcat function. As soon as I removed that function (from some above code) then all of a sudden things were beautiful. So I've coded around using strcat.

Chauncey
I'm no pro. But I thought that declaring const char* would just make the address to the start of the string constant. Therefore, the data to which the pointer points to is editable. No?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chauncey:
I guess I'm wrong. And I was using strcat with a const char* as well when I shouldnt have been. No bugs with strcat.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The compiler shouldn't let you do that is what I'm saying. Something's wrong, either with the compiler or with the header files.

Speaking of header files - did you include the header files for the functions you use ?

EDIT: C lets you do that - with a warning if you include the header file and with no warning if you don't include the header file.

In C++ it is an error either way.

You should include the header files for functions you use, and enable all compiler warnings.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I have included . But i get no warnings regarding this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

tkurowski wrote:
Yes, I have included . But i get no warnings regarding this.

Did you enable all the compiler warnings ?

(On a side note, this is one of the reasons it's a good idea to use a C++ compiler even if you program in C.)

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is this possible in avr studio?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you mean Atmel Studio 6:
- Rightclick on your project in the Solution Explorer
- Properties
- Toolchain
- AVR/GNU C compiler
- Warnings
- All warnings (-Wall)

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

interesting yet. I have all warnings on. I never got the warnings though.

PS: THANKS TO EVERYBODY FOR YOUR HELP HERE!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok I get them. They're just hidden.

Is it ok for me to do this if pGsmBuffer is a const char*:

strlwr((char*) pGsmBuffer);

?

Or should I just do:

strlwr(gsmBuffer);

? which is a char array.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have a const pointer to something, you're not supposed to change that something using that pointer.

That's (hopefully) why you declared it const.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

its a const pointer to a character array. but the array contents change. Isnt that a good reason to cast it as a char* when necessary?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

tkurowski wrote:
its a const pointer to a character array. but the array contents change. Isnt that a good reason to cast it as a char* when necessary?

Read them from right to left, or something to that effect.

const char *p; // p is a pointer to a char const
               // you can change p, but not *p

char * const p; // p is a const pointer to a char
                // you can change *p, but not p

const char * const p; // p is a const pointer to a char const.
                      // You can't change either

If you want to change the array, you should not declare your pointer to it const.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Stupid const! Thank you for the elegant explanation :) Very much appreciated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Stupid const!

Nothing specific to 'const', AFAIK. The same reasoning (e.g. what the keyword acts upon determined by its position) would apply to e.g. 'volatile'.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

They're just hidden.

In my copy of AS6 at the end of the build there is a tab that lists all the errors and warnings parsed from the actual build output in an easy to digest form. Does your AS6 not have this?

By the way to add to what Chaunicey says - search out a tool called "cdecl" (you'll even find websites online where you can use it). It is a robot for explaining C variable declarations in (easy to understand?) English. It has a sibling called cundecl into which you can type an English description of what you want and it shows the C syntax (but this is quite picky about your input vocabulary). Both these utilities are in the "cutils" package on Debian or Ubunutu.

EDIT: took a while for my AS6 to get started but the tab is called "Error list".

Last Edited: Mon. Jun 4, 2012 - 01:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
took a while for my AS6 to get started but the tab is called "Error list".

That's one thing that dramatically improved when I swapped my hard drive for a solid state disk. Program startup time is a fraction of what it used to be.

Sid

Life... is a state of mind