strstr() gibt keinen NULL pointer zurück? (atmega 2560)

OP #5914168
Lesenswert?

Hallo zusammen,

ich habe folgendes Problem:
Ich sende einen String den ich aus einer Datei lese per UART an den MCU 
(atmega 2560). Dort will ich aus diesem mit strstr() X und Y Koordinaten 
extrahieren.
Leider bleibt der Code in der While-Schleife hängen da scheinbar 
strstr() nie einen NULL Pointer zurück gibt. Ist der NULL Character '\0' 
zur Beendung des Strings falsch gesetzt?
Ich kann meinen Fehler leider nicht finden. Vielleicht könnt ihr mir 
helfen!?

Ich sende den String: "G01 X69.204775 Y23.337389 Z-0.100000 G01 
X80.964849 Y21.666507 Z-0.100000 G00 Z0.100000 (End cutting path id: 
path4285"

Zurück bekomme ich am Serial Port:
1
G01 X69.204775 Y23.337389 Z-0.100000 G01 X80.964849 Y21.666507 Z-0.100000 G00 Z0.100000 (dppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp
 usw.

Mein Code sieht folgendermaßen aus ( zu beachten USART_Transmit('p'); um 
das while loop zu zeigen):
1
void USART_Init(unsigned int ubrr); 
2
void USART_Transmit(unsigned char data); 
3
unsigned char USART_Receive( void );
4
char uart_char;
5
char uart_string[100] = {""};
6

7
int main(void) 
8
{ 
9
  int char_counter = 0;
10
  USART_Init(MYUBRR); 
11
  while(uart_char != '('){
12
    uart_char = USART_Receive();
13
    uart_string[char_counter] = uart_char;
14
    char_counter++;
15
  }
16
  uart_string[char_counter] = '\0';
17
  
18
  for(int i = 0;i<sizeof(uart_string);i++){
19
    USART_Transmit(uart_string[i]);
20
  }
21

22
  char *hier;
23
  char x_values[50][7];
24
  char y_values[50][7];
25
  int number_of_coordinates = 0;
26
  USART_Transmit(sizeof(uart_string));
27
  while( (hier = strstr(uart_string, "G01 X")) != NULL){
28
    strncpy(x_values[0],hier+5,6);
29
    strncpy(y_values[0],hier+5+11,6);     
30
    number_of_coordinates++;
31
    USART_Transmit('p');
32
  }
33
  USART_Transmit('r');
34
  uint8_t coordinates [number_of_coordinates][2];
35
  for(int i=0;i<number_of_coordinates;i++){
36
    coordinates[i][0] = (int) atof(x_values[i]);
37
    coordinates[i][1] = (int) atof(y_values[i]);
38
  }
39
}
Gast #5914176
Lesenswert?

Hans L. schrieb:
1
while( (hier = strstr(uart_string, "G01 X")) != NULL) {
2
    strncpy(x_values[0],hier+5,6);
3
    strncpy(y_values[0],hier+5+11,6);
4
    number_of_coordinates++;
5
    USART_Transmit('p');
6
}

Da du innerhalb der while Schleife den gefundenen String nicht aus 
uart_string entfernst, findest du ihn immer wieder erneut.
Gast #5914197
Lesenswert?

Hans L. schrieb:
> while( (hier = strstr(uart_string, "G01 X")) != NULL){
>     strncpy(x_values[0],hier+5,6);
>     strncpy(y_values[0],hier+5+11,6);
>     number_of_coordinates++;
>     USART_Transmit('p');
>   }
Suche wird immer an der gleichen Stelle fortgesetzt!
1
char *pNext;   // !!!!
2

3
int main(void) 
4
{ 
5
  int char_counter = 0;
6
  USART_Init(MYUBRR); 
7
  while(uart_char != '('){
8
    uart_char = USART_Receive();
9
    uart_string[char_counter] = uart_char;
10
    char_counter++;
11
  }
12
  uart_string[char_counter] = '\0';
13
  
14
  for(int i = 0;i<sizeof(uart_string);i++){
15
    USART_Transmit(uart_string[i]);
16
  }
17

18
  char *hier;  
19
  char x_values[50][7];
20
  char y_values[50][7];
21
  int number_of_coordinates = 0;
22
  USART_Transmit(sizeof(uart_string));
23

24
  pNext=uart_string; //!!!!
25

26
  while( (hier = strstr(pNext, "G01 X")) != NULL){ //!!!!
27
    strncpy(x_values[0],hier+5,6);
28
    strncpy(y_values[0],hier+5+11,6);     
29
    number_of_coordinates++;
30
    USART_Transmit('p');
31
    pNext=hier; // !!!! hier wird bei der Suche weiter gesprungen
32
  }
33
  USART_Transmit('r');
34
  uint8_t coordinates [number_of_coordinates][2];
35
  for(int i=0;i<number_of_coordinates;i++){
36
    coordinates[i][0] = (int) atof(x_values[i]);
37
    coordinates[i][1] = (int) atof(y_values[i]);
38
  }
39
}

So sollte es gehen.
OP #5914230
Lesenswert?

Vielen Dank!!! :-)
Jetzt macht es Sinn!!

habe es jetzt so umgesetzt und es funktioniert:
1
  while( (hier = strstr(uart_string, "G01 X")) != NULL){
2
    strncpy(x_values[number_of_coordinates],hier+5,6);
3
    strncpy(y_values[number_of_coordinates],hier+5+11,6);
4
    strcpy(uart_string,hier+5);     
5
    number_of_coordinates++;
6
  }
#5914271
Lesenswert?

Hans L. schrieb:
> strncpy(x_values[0],hier+5,6);

Das funktioniert nicht so, wie du dir das vorstellst.

Wenn in den 6 Zeichen keine '\0' gefunden wird, wird auch keine kopiert.
Der String in x_Values ist nicht terminiert.

Warum überhaupt der Umweg über das 2D-char-Array.
atof hört da auf, wo es keine gültig Zahl erkennt.

Warum überhaupt atof, wenn du eigentlich atoi möchtest.
besser noch strtoul.
Gast #5914593
Lesenswert?

Es geht kürzer und klarer.
Das Einfügen der Z-Koordinaten sind jetzt ein Kinderspiel.

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <math.h>
5

6
char uart_string[]="G01 X69.204775 Y23.337389 Z-0.100000 G01 X80.964849 Y21.666507 Z-0.100000 G00 Z0.100000";
7

8
int main(void)
9
{
10
    char *px;
11
    float coordinates[10][2];
12

13
    int number_of_coordinates = -1;
14

15
    px=uart_string;
16

17
    memset(coordinates,0,sizeof(coordinates));
18

19
    while (*px)
20
    {
21
        switch (*px)
22
        {
23
            case 'G':
24
                number_of_coordinates++;
25
                break;
26

27
            case 'X':
28
                px++;
29
                coordinates[number_of_coordinates][0]=atof(px);
30
                break;
31

32
            case 'Y':
33
                px++;
34
                coordinates[number_of_coordinates][1]=atof(px);
35
                break;
36

37
            default:
38
                break;
39
        }
40
        px++;
41
    }
42

43
    for (number_of_coordinates=0;number_of_coordinates<10;number_of_coordinates++)
44
    {
45
        printf("%d\tx=%f\t\ty=%f\r\n",number_of_coordinates,coordinates[number_of_coordinates][0],coordinates[number_of_coordinates][1]);
46
    }
47
}

Vorteil :

-weniger Variable
-weniger Code
-vermutlich wesentlich schneller
-leichtere Ausbaufähigkeit

Auch für Prozessoren mit wenig SRAM geeignet, da strstr() ein 
Speicherfresser ist.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren