I'm trying to write a file with hex values representation in C
something like this:
char Msg[4] = {0x3f, 0x2a, 0x01, 0x52};
the output that I'm looking for into the file is like this: "3f2a0152"
I was using fprintf to append some text before the hex representation, but I was not able to write it successfully
FILE *LOG_FILE= fopen("./Hex.log", "a");
fprinf(LOG_FILE, "%d OUT %x", Timestamp, Msg);
fclose(LOG_FILE);
Any advise?
The line:
fprintf(LOG_FILE, "%d OUT %x", Timestamp, Msg);
will decay Msg to a pointer (address of the 0x3f) and then print that out.
What you need to do is to output each element as a two-digit hex value, something like:
fprintf(LOG_FILE, "%d OUT %02x%02x%02x%02x\n", Timestamp, Msg[0], Msg[1], Msg[2], Msg[3]);
In addition, they should probably be specified as unsigned char so they don't sign-extend when passing to fprintf. Otherwise, you'd have to do something ugly like:
fprintf(LOG_FILE, "%d OUT %02x%02x%02x%02x\n", Timestamp, (unsigned)(Msg[0]),
(unsigned)(Msg[1]), (unsigned)(Msg[2]), (unsigned)(Msg[3]));
If you wanted a more general solution, you could put together a function to do it, something like:
void LogHex(FILE *fh, int tstamp, char *preamble, unsigned char *mem, size_t sz) {
fprintf(fh, "%d %s", tstamp, preamble);
for (size_t i = 0; i < sz; ++i) {
fprintf(fh, "%02x", mem[i]);
}
fprintf(fh, "\n");
}
:
LogHex(LOG_FILE, Timestamp, "OUT ", Msg, sizeof(Msg));
Related
Got this code right here to print out the name of an opened file (its a height map in case you were wondering) and every time I try to print out I get format warnings, which format specifier should I use for this?
unsigned char* data = stbi_load("textures/height.png", &width, &height, &nr_components, 0);
printf("Loaded file: %u\n", data);
If your goal is to print the address where the data was loaded, that would be %p:
printf("Loaded file: %p\n", (void*)data);
If you want to print the actual data, byte by byte, you should loop over the bytes and use %hhu (for decimal) or %hhx (for hexadecimal):
printf("Loaded file:\n");
for(int i = 0; i < width*height*nr_components; ++i)
printf("%hhx ", data[i]);
printf("\n");
data doesn't contain the name of the file though, so if you want to print just the name, then print that same string that you passed to stbi_load:
const char *filename = "textures/height.png";
unsigned char* data = stbi_load(filename, &width, &height, &nr_components, 0);
printf("Loaded file: %s\n", filename);
I have this function that communicates with a tcp server
char write_buffer[128];
char read_buffer[128];
char hint_status[4];
char Fsize[10];
FILE *score;
char lnk[1024];
int Fsize_max = 1024*1024*1024;
int hint(){
if (connect(tcpfd, tcpres->ai_addr, tcpres->ai_addrlen) < 0) {
printf("\n Error : Connect Failed \n");
return 0;
}
sprintf(write_buffer,"GHL %s\n",PLID);
n=write(tcpfd, write_buffer,strlen(write_buffer));
n=read(tcpfd, read_buffer, 128);
sscanf(read_buffer, "%s %s %s %s %s\n", message_type, hint_status, Fname, Fsize, lnk);
if(strcmp(hint_status, "NOK") == 0){
return 0;
};
if (atoi(Fsize) > Fsize_max){
printf("size_overflow\n");
return 0;
}
score = fopen(Fname, "w+");
fwrite(lnk, 1, sizeof(lnk), score);
fclose(score);
return 0;
}
That sends information to the server and in return is supposed to receive "RHL status [Fname Fsize Fdata]" in what status is to check if the it return a file or not, and
the filename Fname (it comes in .PNG or .JPG)
the file size Fsize, in bytes;
the contents of the selected file (Fdata).
I am supposed to receive RHL OK something.PGN 99123(for example) data and I am receiving RHL OK 5 12 or some times segmentation fault.
I know I am doing something wrong but I am not surely what.
Does any body have a clue on what is wrong with it?
Does any body have a clue on what is wrong with it?
Yes
Missing null character
n=write(tcpfd, write_buffer,strlen(write_buffer)); does not write a string as no null character is sent.
Consider
n=write(tcpfd, write_buffer,strlen(write_buffer) + 1);
sscanf(read_buffer... expects a string, yet read_buffer[] is not certainly null character terminated.
Use return value n to examine read_buffer[] and determine and append a '\0' as needed.
Candidate problem: no width
Without widths, code risks buffer overflow and undefined behavior (UB).
char Fsize[10]; cannot save as text, Fsize_max, or "1073741824", which needs size 11.
Use widths to prevent buffer overflow.
Use better scan checking
// sscanf(read_buffer, "%s %s %s %s %s\n",
// message_type, hint_status, Fname, Fsize, lnk);
char message_type[10]; // True size is unknown as not posted by OP.
char Fname[100]; // True size is unknown as not posted by OP.
int n = 0;
sscanf(read_buffer, "%9s %3s %99s %9s %1023s %n",
message_type, hint_status, Fname, Fsize, lnk, &n);
if (n == 0 || read_buffer[n]) {
TBD_CODE_Handle_Error():
}
For error checking, do not assume text in int range.
// if (atoi(Fsize) > Fsize_max){
if (atoll(Fsize) > Fsize_max){
so Im writing a code to get scanf a text file and return a format text message log. I'm stuck wondering how to scan strings from file at a certain point and print every string beyond that point E.X When the file scans the line
"332982000 2055552002 2055551001 7 Mr Webb, can I ask you a question?" I scan the first 4 numbers as integers and scan the rest of the written text into an char array starting at "Mr. Webb".
I tried using a for loop with fscanf to scan into an array but it didnt work. I was also thinking I could use malloc just to save space but I dont know what to put in the sizeof argument. Any help would be GREATLY appreciated!
int posix;
int phone1;
int phone2;
int textsize;
int val, val2;
char line[256];
char text[3000];
int len=strlen(line);
int i=0;
printf("\n\nTime %s %s", argv[2], argv[3]);
printf("\n======================================================================================\n\n\n");
FILE* textfile= fopen(argv[1],"r");
fscanf(textfile, "%d %d %d %d %s", &posix, &phone1, &phone2, &textsize, text);
while( fgets(line, sizeof(line), textfile) ) {
val= atoi(argv[2]);
val2=atoi(argv[3]);
if ( (val==phone1) && (val2==phone2) ) {
printf(" %s ", text); //only prints Mr
text=(char*)malloc(sizeof())//tried malloc but not too sure how to use it correctly
for (i=0; i<len; i++) { //tried using for loop here didnt work.
fscanf("%s", text);
}
sortText(phone1, phone2, textsize, text);
//readableTime(posix);
}
else if ( (val2==phone1) && (val==phone2) ) {
printf(" %s ", text);
sortText(phone1, phone2, textsize, text);
//readableTime(posix);
}
fscanf(textfile, "%d %d %d %d %s", &posix, &phone1, &phone2, &textsize, text);
}
fclose(textfile);
return 0;
}
At first, read the entire file into a malloc'd char array. The fseek and ftell give you the file size:
// C99
FILE *fp = fopen("file", "r");
size_t filesize;
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *filetext = malloc(filesize + 1);
fread(filetext, 1, filesize, fp);
filetext[filesize] = 0;
Then use a buffer for a single line with the size of the entire file so you surely have enough size. sscanf() can be used to read stuff from a string.
int readbytes;
for(int i=0; i < filesize; i+=readbytes) {
char line[filesize];
int posix, phone1, phone2, textsize;
if(EOF == sscanf(
&filetext[i], "%d%d%d%d%[^\n]%n", &posix, &phone1,
&phone2, &textsize, line, &readbytes))
{
break;
}
printf("%d %d %d %d '%s' %d\n", posix, phone1, phone2, textsize, line, readbytes);
}
The format specifier '%[^\n]' means: every character until the next newline character. The format specifier '%n' gives you the number of bytes that have been read with this sscanf call so far, effectively your line size, that you can use to advance the iterator.
I'm really new to Sqlite and I want to write a text file (xml actually) from an sqlite database table automatically using C. How can I do that? I got these to select some data from database and print in terminal:
int callback(void * ptr, int resultados, char ** STR1, char **STR2) {
int i;
for(i = 0; STR1[i] != NULL; i++) {
printf("%s = %s\n", STR2[i], STR1[i]);
}
return 0;
}
and inside of main:
/* Open database */
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
sql = "SELECT * from COMPANY";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
and then I tried to change the callback, to get STR1 and STR2 to write a text file, something like this:
int callback(void * ptr, int resultados, char ** STR1, char **STR2) {
int i;
char teste[1024];
FILE *pFile;
pFile = fopen ("test.txt", "a+");
for(i = 0; STR1[i] != NULL; i++) {
printf("%s = %s\n", STR2[i], STR1[i]);
snprintf (teste, sizeof(teste), "%s %s\n", STR2[i], STR1[i]);
fwrite (teste, 1, sizeof(teste), pFile);
fflush(pFile);
}
return 0;
}
but when I try to open the test.txt, gedit says 'There was a problem opening the file /home/kdan/test/test.txt. The file you opened has some invalid characters', and the text contains a bunch of random characters, numbers and symbols. So I'm not being able to get the selected data and convert to string D: should I try to use something like sqlite_mprintf, sqlite_vmprintf, sqlite_exec_printf or sqlite_get_table_printf? Would it be right? Or is there another way to select the data and format it to a variable char? Sorry for my rusty english.
Edited: It is working now, just needed to use fputs instead of fwrite, here is the code working:
int callback(void * ptr, int resultados, char ** STR1, char **STR2) {
int i;
char teste[1024];
FILE *pFile;
pFile = fopen ("test.txt", "a");
for(i = 0; STR1[i] != NULL; i++) {
printf("%s = %s\n", STR2[i], STR1[i]);
snprintf (teste, sizeof(teste), "%s %s\n", STR2[i], STR1[i]);
fputs (teste, pFile);
fflush(pFile);
}
return 0;
}
Haven't tested your code but I think the problem is with the fwrite() call.
From the linux manpages:
NAME
fread, fwrite - binary stream input/output
SYNOPSIS
[...]
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
DESCRIPTION
[...]
The function fwrite() writes nmemb elements of data, each size bytes
long, to the stream pointed to by stream, obtaining them from the loca‐
tion given by ptr.
STR2[i] and STR1[i] may have a total length less than sizeof teste. For illustrative purpose, let's say STR2[i] is "foo" and STR1[i] is "bar". After the snprintf() call, teste will have the following contents:
teste[0] 'f'
teste[1] 'o'
teste[2] 'o'
teste[3] ' '
teste[4] 'b'
teste[5] 'a'
teste[6] 'r'
teste[7] '\n'
teste[8] '\0'
teste[9] onwards uninitialised
Since fwrite is for writing to a binary stream, it will NOT stop writing after reaching the '\0' byte. Instead it will keep writing all the uninitialised characters in teste. In this case it will write 1015 uninitialised characters.
The proper way to write to a text stream is to use either fputs() (in which case you should remove the '\n' in your string) or fprintf(). Or, if you really want to use fwrite(), ask it to print strlen(teste) bytes (which will be 8 in this case) instead of sizeof teste which is 1024.
Finally, although not related to your problem, if you are not reading from the file you should fopen() it with "a" instead of "a+".
I just want to output 3 integers from the file. Why this doesn't work? I get -1079184140 and similar.
int main(int argc, char *argv[])
{
FILE* stream = fopen(argv[2], "r");
char line[80];
for (int i = 0; i < 3; i++)
{
fgets(line, 80, stream);
printf("%d \n", line);
}
fclose(streamForInput);
}
I would use sscanf.
int number;
sscanf (line, "%d", &number);
printf ("%d \n", number);
That will pull the first integer on a line. This is not the most secure or robust way, but that is out of scope.
PS:
fclose(streamForInput);
Should be:
fclose(stream);
Hmm. The first problem is:
printf("%d \n", line);
because line is a char[]. But you use a %d to output it, so you output line, which is an address. So printf prints the address of line... instead you coud use printf ("%d", atoi(line));
To print a string, which line is, use %s:
printf("%s \n", line);
Now, if it really were an integer, you could use %d:
int num = atoi(line);
printf("%d \n", num );
What you're seeing is the result of treating a pointer type (which is what a string in C basically is) as an integer type. Since pointers hold memory addresses, that -1079184140 is the actual address the pointer holds, represented as a 32 bit signed integer.
If you know exactly the content of the file (three numbers separated by white space), why not directly read it?
if (fscanf(stream, "%d%d%d", &foo, &bar, &baz) < 3)
// handle error
printf("%d\n%d\n%d\n", foo, bar, baz);
But if you want to read lines, there are already other good answers.
To read a file line by line for integers
void read_file(char *filename, int *readbuff, int size)
{
FILE *fp = fopen(filename,"r");
if(fp == NULL){
printf("Failed to open file %s \n", filename);
return;
}
/*the condition in for loop checks if the integer was read into
readbuff[i] and the readbuff is not overflown*/
for(int i = 0 ; fscanf(fp,"%d\n",&readbuff[i]) == 1 && i < size; ++i);
fclose(fp);
return;
}