I have found strange behavior of sscanf
parsing double quoted string on i386 machine.
My code:
char string[] = "\"1597821828\" \"MODIFY\" \"/fullpath/test2\"";
printf("line : %s", string);
int total;
char store_date[12] = "", store_etat_watch[24] = "", store_path[1024] = "";
printf("stores init:%s,%d , %s,%d , %s,%d \n",
store_date, strlen(store_date),
store_etat_watch, strlen(store_etat_watch),
store_path, strlen(store_path));
total = sscanf(string,"%s %s %s", store_date, store_etat_watch, store_path);
printf("stores brut:%s,%d , %s,%d , %s,%d \n",
store_date, strlen(store_date),
store_etat_watch, strlen(store_etat_watch),
store_path, strlen(store_path));
I compile it on a debian arm64 an execute it (here is my Makefile):
CC = gcc
ERROR_CFLAGS = -Wall -W -pedantic -Wextra -Werror CFLAGS = -static -g -O0 $(ERROR_FLAGS) -D_REENTRANT -DLinux LDFLAGS = $(ERROR_FLAGS)
all: sscanf_test
sscanf_test: sscanf_test.c $(CC) $(CFLAGS) sscanf_test.c -o sscanf_test .PHONY:clean
clean: rm -f sscanf_test
result:
line : "1597821828" "MODIFY" "/fullpath/test2"
stores init:,0 , ,0 , ,0
stores brut:"1597821828",12 , "MODIFY",8 , "/fullpath/test2",17
That's the result I expect. Then I compile it on ubuntu i386 and execute it:
result:
line : "1597821828" "MODIFY" "fullpath/test2"
stores init:,0 , ,0 , ,0
stores brut:"1597821828""MODIFY",20 , "MODIFY",8 ,"/fullpath/test2",17
The first string is not correctly parsed. If the string doesn't begin with double quote: 'no problem'.
char string[]="1597821828 \"MODIFY\" \"/fullpath/test2\"";
result:
line : "1597821828" "MODIFY" "/fullpath/test2"
stores init:,0 , ,0 , ,0
stores brut:1597821828,10 , "MODIFY",8 , "/fullpath/test2",17
I do have to parse string beginning with double quote.
Somebody can help me ?
char store_date[12]
is too small to store the the string *1597821828*
(Quote character replaced by *
for clarity.). Result: undeifned behavior (UB). A string of length 12 needs at least 12+1 char
. The +1 is for the null character.
That it seemed to work on some systems is normal for UB; UB isn't "required to fail", it's "anything can happen". If the memory you stepped on outside store_data[12]
happened to not be something the compiler was using for anything needed later in the function, it can happen to work. That's what makes undefined behaviour so nasty: testing can't always reveal it.
Make the destination array large enough and use widths with "%s"
.
// char store_date[12]="";
// total=sscanf(string,"%s",store_date);
char store_date[12+1]="";
total=sscanf(string,"%12s",store_date);
Mis-matched specifier with strlen()
// printf("%d \n",strlen(store_path));
printf("%zu\n",strlen(store_path));