I'm learning C and don't understand how one could handle case when memory areas retuned by malloc are overlapping. Here is a little demo program
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void print_mem(char *from, int64_t amount) {
int step = 0x8;
for (int i = 0; i < amount; i = i + step) {
printf("%x = ", from + i);
for (int j = 0; j < step; ++j) {
int c = *(from + i + j);
if (isprint(c) == 0) {
c = ' ';
}
printf("%02x (%c) ", *(from + i + j), c);
}
printf("\n");
}
}
int main() {
// len = 48
// 222222222222222222222222222222222222222222222222
// 111111111111111111111111111111111111111111111111
char *str1 = (char *) malloc(0x10 * sizeof(char));
printf("str1: 0x%x\n", str1);
char *str2 = (char *) malloc(0x10 * sizeof(char));
printf("str2: 0x%x\n", str2);
printf("\n\nInitial memory layout\n");
print_mem(str1, 0x80);
printf("\n\nType str2: ");
scanf("%s", str2);
printf("Memory after scanf str2\n");
print_mem(str1, 0x80);
printf("\n\nType str1: ");
scanf("%s", str1);
printf("Memory after scanf str1\n");
print_mem(str1, 0x80);
printf("\n\nstr2 = %s\n", str2);
printf("str1 = %s\n", str1);
return 0;
}
And the output
str1: 0x64c010
str2: 0x64c020
Initial memory layout
64c010 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c018 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c020 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c028 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c030 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c038 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c040 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c048 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c050 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c058 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c060 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c068 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c070 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c078 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c080 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c088 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
Type str2: 222222222222222222222222222222222222222222222222
Memory after scanf str2
64c010 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c018 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c020 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c028 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c030 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c038 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c040 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c048 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c050 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c058 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c060 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c068 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c070 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c078 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c080 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c088 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
Type str1: 111111111111111111111111111111111111111111111111
Memory after scanf str1
64c010 = 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1)
64c018 = 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1)
64c020 = 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1)
64c028 = 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1)
64c030 = 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1)
64c038 = 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1) 31 (1)
64c040 = 00 ( ) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c048 = 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2) 32 (2)
64c050 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c058 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c060 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c068 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c070 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c078 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c080 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
64c088 = 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( ) 00 ( )
str2 = 11111111111111111111111111111111
str1 = 111111111111111111111111111111111111111111111111
Tried scanf("%s10", str2); but it also not worked as expected when I input long lines
From The Open Group Base Specifications:
The malloc() function shall allocate unused space for an object whose
size in bytes is specified by size and whose value is unspecified.
The order and contiguity of storage allocated by successive calls to
malloc() is unspecified. The pointer returned if the allocation
succeeds shall be suitably aligned so that it may be assigned to a
pointer to any type of object and then used to access such an object
in the space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to an object
disjoint from any other object. The pointer returned points to the
start (lowest byte address) of the allocated space. If the space
cannot be allocated, a null pointer shall be returned.z If the size of
the space requested is 0, the behavior is implementation-defined: the
value returned shall be either a null pointer or a unique pointer.
Each allocation yields a pointer to an object disjoint from any other object. There's no memory overlapping. The order and contiguity is also not specified, they may or may not be stored in consecutive memory locations.
What you have here is a heap-based buffer overflow. You're overwriting the contents of str2 when you write pass the end of str1, as the allocations are placed in memory consecutively in this case. Does this mean that the allocations overlap? No, they do not.
That being said, you should:
Check the return value of malloc(). It returns NULL on failure.
Not cast the result of malloc() and family.¹ It's redundant and may hide a bug.
Aside: The correct format specifier to print a pointer is %p, and the pointer must be cast to void *.
printf("str1: %p\n", (void *) str1);
Else the code invokes undefined behaviour.
Re:
Tried scanf("%s10", str2); but it also not worked as expected when I
input long lines
Answer: scanf() should not be used as a user-input interface. Switch to fgets. The call to scanf() can be replaced with:
fgets (buf, sizeof buf, stdin);
But if you insist upon using scanf(), then
scanf("%s10", str2);
should be:
scanf ("%9s", str2);
And check its return value.
[1] — Do I cast the result of malloc?
Related
I call a stored procedure using JDBC:
Connection con = DriverManager.getConnection("jdbc:sqlserver://myhost;databaseName=mydb;encrypt=false","user", "pass");
con.setAutoCommit(false);
CallableStatement cs = con.prepareCall("{call abc(?,?,?,?,?,?,?)}");
cs.setDate(1, java.sql.Date.valueOf(LocalDate.of(2023, 1, 10)));
cs.setDate(2, java.sql.Date.valueOf(LocalDate.of(2023, 1, 9)));
cs.setString(3, "PROD");
cs.registerOutParameter(4, Types.NUMERIC);
cs.registerOutParameter(5, Types.NUMERIC);
cs.registerOutParameter(6, Types.NUMERIC);
cs.registerOutParameter(7, Types.NUMERIC);
cs.executeQuery();
I get a SQLServerException:
2023-01-13T11:22:48.975-06:00 DEBUG 21888 --- [restartedMain]
c.m.s.jdbc.internals.SQLServerException : ***
SQLException:SQLServerCallableStatement:5
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not
return a result set. The statement did not return a result set.
But I get no error calling it with Hibernate:
StoredProcedureQuery query = em.createStoredProcedureQuery("abc")
.registerStoredProcedureParameter(
"date1",
LocalDate.class,
ParameterMode.IN
)
.registerStoredProcedureParameter(
"date2",
LocalDate.class,
ParameterMode.IN
)
.registerStoredProcedureParameter(
"name",
String.class,
ParameterMode.IN
)
.registerStoredProcedureParameter(
"value1",
BigDecimal.class,
ParameterMode.OUT
)
.registerStoredProcedureParameter(
"value2",
BigDecimal.class,
ParameterMode.OUT
)
.registerStoredProcedureParameter(
"value3",
BigDecimal.class,
ParameterMode.OUT
)
.registerStoredProcedureParameter(
"value4",
BigDecimal.class,
ParameterMode.OUT
)
.setParameter("date1", LocalDate.of(2023, 1, 10))
.setParameter("date2", LocalDate.of(2023, 1, 9))
.setParameter("name", "PROD");
query.execute();
log.info("value2 is {}", query.getOutputParameterValue("value2"));
What am I doing wrong with my JDBC call?
I looked at the TRACE log from the SQL Server driver. The only difference in bytes going going to SQL Server is ^ and H in the first line:
JDBC
03 01 02 26 00 5E 01 00 16 00 00 00 12 00 00 00 ...&.^..........
02 00 00 00 00 00 00 00 00 00 01 00 00 00 FF FF ................
0A 00 00 00 00 00 E7 40 1F 09 04 D0 00 34 96 00 .......#.....4..
45 00 58 00 45 00 43 00 20 00 74 00 65 00 6D 00 E.X.E.C. .a.b.c.
Hibernate
03 01 02 26 26 00 48 01 00 16 00 00 12 00 00 00 ...&.H..........
02 00 00 00 00 00 00 00 00 00 01 00 00 00 FF FF ................
0A 00 00 00 00 00 E7 40 1F 09 04 D0 00 34 96 00 .......#.....4..
45 00 58 00 45 00 43 00 20 00 74 00 65 00 6D 00 E.X.E.C. .a.b.c.
The Hibernate code calls execute() which expects no result set. However, the JDBC code is calling executeQuery() and that expects a result set. Since the stored procedure doesn't return a result set, the SQL Server exception is thrown.
I changed the JDBC code to execute(), and it works the same as the Hibernate code.
Given:
A machine running Debian 10 and using the french keyboard mapping.
A dump of keystrokes correspoding to "azerty" obtained using:
sudo cat /dev/input/by-id/usb-Logitech_USB_Keyboard-event-kbd > test_keylogger_azerty
The following code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <xcb/xcb.h>
#include <xcb/xcb_keysyms.h>
#include <X11/Xlib.h>
#include <linux/input.h>
int main(int ac, char **av)
{
int fd, col;
xcb_connection_t *connection;
xcb_key_symbols_t *symbols;
struct input_event ev;
if (ac != 3) {
printf("Usage: %s <dump file> <symbol table index>\n", av[0]);
exit(EXIT_FAILURE);
}
connection = xcb_connect(NULL, NULL);
symbols = xcb_key_symbols_alloc(connection);
col = atoi(av[2]);
fd = open(av[1], O_RDONLY);
while (read(fd, (void *) &ev, sizeof(ev))) {
if (ev.type == EV_KEY && ev.value == 1)
printf("type: %x code: %x value: %2x => %s\n",
ev.type, ev.code, ev.value,
XKeysymToString(xcb_key_symbols_get_keysym(symbols, ev.code, col)));
}
printf("\n");
close(fd);
return(EXIT_SUCCESS);
}
A test run with xev tell me that: a == 24, b == 25 [...] y == 29.
Nevertheless, when i run my program, the obtained code don't match (and, as a result, the guessed corresponding symbol doesn't match too):
$ ./reverse_kl test_keylogger_azerty 0
type: 1 code: 10 value: 1 => egrave
type: 1 code: 11 value: 1 => underscore
type: 1 code: 12 value: 1 => ccedilla
type: 1 code: 13 value: 1 => agrave
type: 1 code: 14 value: 1 => parenright
type: 1 code: 15 value: 1 => equal
type: 1 code: 1c value: 1 => t
type: 1 code: 1d value: 1 => y
type: 1 code: 2e value: 1 => l
if i modify my code that way:
$ diff reverse_kl.c{.ref,}
33c33
< XKeysymToString(xcb_key_symbols_get_keysym(symbols, ev.code , col)));
---
> XKeysymToString(xcb_key_symbols_get_keysym(symbols, ev.code + 8 , col)));
It works better:
$ ./reverse_kl test_keylogger_azerty 0
type: 1 code: 10 value: 1 => a
type: 1 code: 11 value: 1 => z
type: 1 code: 12 value: 1 => e
type: 1 code: 13 value: 1 => r
type: 1 code: 14 value: 1 => t
type: 1 code: 15 value: 1 => y
type: 1 code: 1c value: 1 => Return
type: 1 code: 1d value: 1 => Control_L
type: 1 code: 2e value: 1 => c
Also, note that, for key 'a', i have the code 10 and adding 8 still don't give me 24 but it's working...
If anyone could help me understanding this strange behaviour ...
EDIT:
Added an hexadecimal dump of the trace as requested:
0000000 66 35 4d 5d 00 00 00 00 2b 7c 04 00 00 00 00 00
0000020 04 00 04 00 28 00 07 00 66 35 4d 5d 00 00 00 00
0000040 2b 7c 04 00 00 00 00 00 01 00 1c 00 00 00 00 00
0000060 66 35 4d 5d 00 00 00 00 2b 7c 04 00 00 00 00 00
0000100 00 00 00 00 00 00 00 00 66 35 4d 5d 00 00 00 00
0000120 a7 01 0e 00 00 00 00 00 04 00 04 00 14 00 07 00
0000140 66 35 4d 5d 00 00 00 00 a7 01 0e 00 00 00 00 00
0000160 01 00 10 00 01 00 00 00 66 35 4d 5d 00 00 00 00
0000200 a7 01 0e 00 00 00 00 00 00 00 00 00 00 00 00 00
0000220 67 35 4d 5d 00 00 00 00 22 11 01 00 00 00 00 00
0000240 04 00 04 00 14 00 07 00 67 35 4d 5d 00 00 00 00
0000260 22 11 01 00 00 00 00 00 01 00 10 00 00 00 00 00
0000300 67 35 4d 5d 00 00 00 00 22 11 01 00 00 00 00 00
0000320 00 00 00 00 00 00 00 00 67 35 4d 5d 00 00 00 00
0000340 fc fe 03 00 00 00 00 00 04 00 04 00 1a 00 07 00
0000360 67 35 4d 5d 00 00 00 00 fc fe 03 00 00 00 00 00
0000400 01 00 11 00 01 00 00 00 67 35 4d 5d 00 00 00 00
0000420 fc fe 03 00 00 00 00 00 00 00 00 00 00 00 00 00
0000440 67 35 4d 5d 00 00 00 00 ab 31 06 00 00 00 00 00
0000460 04 00 04 00 1a 00 07 00 67 35 4d 5d 00 00 00 00
0000500 ab 31 06 00 00 00 00 00 01 00 11 00 00 00 00 00
0000520 67 35 4d 5d 00 00 00 00 ab 31 06 00 00 00 00 00
0000540 00 00 00 00 00 00 00 00 67 35 4d 5d 00 00 00 00
0000560 1d e7 07 00 00 00 00 00 04 00 04 00 08 00 07 00
0000600 67 35 4d 5d 00 00 00 00 1d e7 07 00 00 00 00 00
0000620 01 00 12 00 01 00 00 00 67 35 4d 5d 00 00 00 00
0000640 1d e7 07 00 00 00 00 00 00 00 00 00 00 00 00 00
0000660 67 35 4d 5d 00 00 00 00 23 58 0a 00 00 00 00 00
0000700 04 00 04 00 08 00 07 00 67 35 4d 5d 00 00 00 00
0000720 23 58 0a 00 00 00 00 00 01 00 12 00 00 00 00 00
0000740 67 35 4d 5d 00 00 00 00 23 58 0a 00 00 00 00 00
0000760 00 00 00 00 00 00 00 00 67 35 4d 5d 00 00 00 00
As a reminder, below is the format of the input_event structure:
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
And, other reminder, keyboard stroke obey the following rules:
type == EV_KEY == 0x01
value may be 0 for event "key released", 1 for "key pressed" and 2 is for "auto-repeat".
I’m trying to pull numbers out of a proprietary database (Lacerte tax software).
They are all whole numbers, stored in 4 bytes. I have put numbers into the program, and then checked out the file with a hex editor. This has allowed me to see how they are stored.
Here are some examples:
-100 = 00 00 59 C0
-4 = 00 00 10 C0
-3 = 00 00 08 C0
-2 = 00 00 00 C0
-1 = 00 00 F0 BF
0 = 00 00 00 00
1 = 00 00 F0 3F
2 = 00 00 00 40
3 = 00 00 08 40
4 = 00 00 10 40
5 = 00 00 14 40
6 = 00 00 18 40
7 = 00 00 1C 40
8 = 00 00 20 40
9 = 00 00 22 40
10 = 00 00 24 40
100 = 00 00 59 40
1,000,000 = 80 84 2E 41
Does anybody have any idea how to convert these hex numbers from the database into decimals?
I'm writing a utility to rip records out of a legacy DB(that we can't query), and I'm having trouble interpreting how a date field is stored.
All Dates will be in MM/DD/YYYY format. Hex will be bytes(2 digits) separated by spaces.
What we know:
Hours and mins are stored in a different location. Adding an hour or min to
the datetime does not effect the 4 bytes in question
The field that corresponds to the Month, day and year is 4 bytes:
01/01/1800 == 70 8E 00 00
01/15/1800 == 7E 8E 00 00
01/16/1800 == 7F 8E 00 00
01/31/1800 == 8E 8E 00 00
02/01/1800 == 8F 8E 00 00
02/02/1800 == 90 8E 00 00
02/15/1800 == 9D 8E 00 00
02/16/1800 == 9E 8E 00 00
02/28/1800 == AA 8E 00 00
02/29/1800 == AB 8E 00 00 #PLACEHOLDER FOR LEAP YEAR
03/01/1800 == AC 8E 00 00
12/01/1800 == BF 8F 00 00
12/02/1800 == C0 8F 00 00
12/03/1800 == C1 8F 00 00
12/15/1800 == CD 8F 00 00
12/16/1800 == CE 8F 00 00
12/30/1800 == DC 8F 00 00
12/31/1800 == DD 8F 00 00
01/01/1801 == DE 8F 00 00
12/31/1801 == 4A 91 00 00
Anyone have any ideas? And yes, I'm familiar with epoch time.
There are 4 bytes. Each new day increments the byte farthest to the left. Once that byte gets to "FF" it adds 1 to the byte to the right of it. Try this.. (Written in Ruby)
def parse_date(hex)
actual_known_date = "1/1/2050".to_date
known_date = "21F30100"
total_days_since_known_date = 0
first_byte = hex[0,2]
second_byte = hex[2,2]
third_byte = hex[4,2]
fourth_byte = hex[6,2]
known_first_byte = known_date[0,2]
known_second_byte = known_date[2,2]
known_third_byte = known_date[4,2]
known_fourth_byte = known_date[6,2]
byte_4_days = known_fourth_byte.hex - fourth_byte.hex
byte_3_days = 0
byte_2_days = 0
byte_1_days = 0
if known_third_byte.hex >= third_byte.hex
byte_3_days = known_third_byte.hex - third_byte.hex
else
byte_4_days -= 1
ktb = known_third_byte.hex + 256
byte_3_days = ktb - third_byte.hex
end
if known_second_byte.hex >= second_byte.hex
byte_2_days = known_second_byte.hex - second_byte.hex
else
byte_3_days -= 1
ktb = known_second_byte.hex + 256
byte_2_days = ktb - second_byte.hex
end
if known_first_byte.hex >= first_byte.hex
byte_1_days = known_first_byte.hex - first_byte.hex
else
byte_2_days -= 1
ktb = known_first_byte.hex + 256
byte_1_days = ktb - first_byte.hex
end
total_days_since_known_date = (byte_1_days + (byte_2_days * 256) + (byte_3_days * (256 * 256)) + (byte_4_days * (256 * 256 * 256)))
number_of_leap_days = 0
date_we_want = actual_known_date - (total_days_since_known_date).days
return date_we_want
end
I am trying to read a structure from a .dat file...
the first integer to be read is the no of readings
then there is the data in following structure format
struct Oven
{
int rec_no;
int temp;
int status;
char string[10];
};
below is the method through which I read the file
int read_and_process_file()
{
int counter;
FILE *ptr_myfile;
struct Oven my_record;
ptr_myfile=fopen("data.dat","rt");
//for no of readings
fread(&no_of_readings,sizeof(no_of_readings),1,ptr_myfile);
for ( counter=1; counter <= 50; counter++)
{
fread(&my_record,sizeof(struct Oven),1,ptr_myfile);
name=my_record.string;
printf("%d : ",my_record.rec_no);
fprintf(ptr_myfile2,"%d : ",my_record.rec_no);
printf("%d : ",my_record.temp);
printf("%d : ",my_record.status);
printf("%s\n",name);
}
fclose(ptr_myfile);
return 0;
}
but i can't read more than 25 records after 25 it keeps on repeating the 25th record...
tried fseek but it skips some records... any help?
This is the output image
UPDATE (Wildplasser) And here is the first 0x200 bytes of the data (wich does look a bit irregular ...)
00000000 b8 0b 00 00 00 00 00 00 54 00 00 00 01 00 00 00 |........T.......|
00000010 42 6f 62 00 cd cd cd cd cd cd cd cd 01 00 00 00 |Bob.............|
00000020 4d 00 00 00 00 00 00 00 43 4c 4f 53 45 44 00 cd |M.......CLOSED..|
00000030 cd cd cd cd 02 00 00 00 2e 00 00 00 00 00 00 00 |................|
00000040 43 4c 4f 53 45 44 00 cd cd cd cd cd 03 00 00 00 |CLOSED..........|
00000050 5f 00 00 00 01 00 00 00 48 61 72 72 79 00 cd cd |_.......Harry...|
00000060 cd cd cd cd 04 00 00 00 44 00 00 00 01 00 00 00 |........D.......|
00000070 48 61 72 72 79 00 cd cd cd cd cd cd 05 00 00 00 |Harry...........|
00000080 63 00 00 00 01 00 00 00 4a 69 6c 6c 00 cd cd cd |c.......Jill....|
00000090 cd cd cd cd 06 00 00 00 53 00 00 00 01 00 00 00 |........S.......|
000000a0 4a 61 6d 65 73 00 cd cd cd cd cd cd 07 00 00 00 |James...........|
000000b0 56 00 00 00 00 00 00 00 43 4c 4f 53 45 44 00 cd |V.......CLOSED..|
000000c0 cd cd cd cd 08 00 00 00 49 00 00 00 00 00 00 00 |........I.......|
000000d0 43 4c 4f 53 45 44 00 cd cd cd cd cd 09 00 00 00 |CLOSED..........|
000000e0 53 00 00 00 01 00 00 00 42 6f 62 00 cd cd cd cd |S.......Bob.....|
000000f0 cd cd cd cd 0d 0a 00 00 00 59 00 00 00 00 00 00 |.........Y......|
00000100 00 43 4c 4f 53 45 44 00 cd cd cd cd cd 0b 00 00 |.CLOSED.........|
00000110 00 46 00 00 00 01 00 00 00 4a 69 6c 6c 00 cd cd |.F.......Jill...|
00000120 cd cd cd cd cd 0c 00 00 00 38 00 00 00 00 00 00 |.........8......|
00000130 00 43 4c 4f 53 45 44 00 cd cd cd cd cd 0d 00 00 |.CLOSED.........|
00000140 00 48 00 00 00 00 00 00 00 43 4c 4f 53 45 44 00 |.H.......CLOSED.|
00000150 cd cd cd cd cd 0e 00 00 00 5e 00 00 00 01 00 00 |.........^......|
00000160 00 4a 61 6d 65 73 00 cd cd cd cd cd cd 0f 00 00 |.James..........|
00000170 00 40 00 00 00 01 00 00 00 4a 69 6c 6c 00 cd cd |.#.......Jill...|
00000180 cd cd cd cd cd 10 00 00 00 56 00 00 00 00 00 00 |.........V......|
00000190 00 43 4c 4f 53 45 44 00 cd cd cd cd cd 11 00 00 |.CLOSED.........|
000001a0 00 43 00 00 00 01 00 00 00 4a 61 6d 65 73 00 cd |.C.......James..|
000001b0 cd cd cd cd cd 12 00 00 00 60 00 00 00 01 00 00 |.........`......|
000001c0 00 42 6f 62 00 cd cd cd cd cd cd cd cd 13 00 00 |.Bob............|
000001d0 00 5e 00 00 00 00 00 00 00 43 4c 4f 53 45 44 00 |.^.......CLOSED.|
000001e0 cd cd cd cd cd 14 00 00 00 55 00 00 00 00 00 00 |.........U......|
000001f0 00 43 4c 4f 53 45 44 00 cd cd cd cd cd 15 00 00 |.CLOSED.........|
It's hard to tell exactly what's going on as your code snippet isn't complete, but here are some things I noticed:
You don't seem to be using the read-in no_of_readings, and instead try to read 50 records. Since you don't check the return value of fread, your program just carries on using whatever the last successful fread read.
You shouldn't be opening the file in text mode if you're not reading text. Line ending conversion could corrupt your data. Use "rb" instead (also the standard C way to open in text mode is just to omit the b, t is nonstandard).
edit: On Windows reading a file in text mode interprets a ctrl-z byte (26) as end of file. This is why your reads stop after the 25th record.
Reading/writing data directly to/from structs like this will result in data files that aren't portable. Better to serialise your struct into bytes manually.
I would suggest checking the return value of the fread to check for errors
int size = fread(&my_record,sizeof(struct Oven),1,ptr_myfile);
if (size != sizeof(struct Oven))
{
perror ("Error reading Line %d", counter);
break;
}
This should give an idea of what went wrong