I get a Suspicious pointer conversion in function main. How to get rid of this? - turbo-c

I'm new here at stackoverflow. The title is my question. Can someone please help me on this. Thanks. I've been working on this for like 3 days.
This part of code encodes the file to a huffman code
void encode(const char *s, char *out)
{
while (*s) {
strcpy(out, code[*s]);
out += strlen(code[*s++]);
}
}
This part of code deciphers the file from a huffman code to a human readable code
void decode(const char *s, node t)
{
node n = t;
while (*s) {
if (*s++ == '0') n = n->left;
else n = n->right;
if (n->c) putchar(n->c), n = t;
}
putchar('\n');
if (t != n) printf("garbage input\n");
}
This part is where I get my error.
int main(void)
{
int i;
const char *str = "this is an example for huffman encoding", buf[1024];
init(str);
for (i=0;i<128;i++)
if (code[i]) printf("'%c': %s\n", i, code[i]);
encode(str, buf); /* I get the error here */
printf("encoded: %s\n", buf);
printf("decoded: ");
decode(buf, q[1]);
return 0;
}

Declare 'buf' in a different line, and not as 'const':
char buf[1024];

The const applies to all the declarations on the line, so you're declaring buf as a const char[1024]. That means that calling encode casts away the constness, resulting in the warning.
Avoid having multiple variable declarations on the same line, unless they are all exactly the same type.

Related

Converting the result from JSON GENERATE to EBCDIC

For one of my requirements I need the JSON GENERATE function in COBOL 6. My problem is, that it returns UTF-8, but I need the data in EBCDIC (CCSID 1140). Is there a way to convert this? Every solution I found uses national data types, but I have to use the NODBCS compiler option, so those don't work.
I do apologize for not first asking a question (but I am too new to StackOverflow to allow that.) The question would be "do you have C++ and can you link C++ with your COBOL?" I just tried this program:
#include <iconv.h>
class myConv
{
public:
static myConv globalConv;
size_t conv(char ** restrict f, unsigned int * restrict flen,
char ** restrict t, unsigned int * restrict tlen)
{
if (ok_)
{
return iconv(cd_, f, flen, t, tlen);
}
else
{
return (size_t)-1;
}
}
private:
myConv()
{
cd_ = iconv_open("1047", // EBCDID
"1208"); // UTF-8
ok_ = (cd_ != (iconv_t)-1);
// possibly indicate what the error is
}
~myConv()
{
if (ok_)
{
if (iconv_close(cd_) != 0)
{
// possibly indicate what the error is
}
}
}
bool ok_;
iconv_t cd_;
};
myConv myConv::globalConv;
extern "C" bool CNV(char * f, unsigned int flen,
char * t, unsigned int tlen)
{
return myConv::globalConv.conv(&f, &flen,
&t, &tlen) != (size_t)-1;
}
and the COBOL call looked like this:
json generate result from grp
call "CNV" using by reference result,
by value length of result,
by reference convertedres,
by value length of convertedres,
returning cres
and cres is a PIC S9(9) COMP data item which will have a non-zero value of the conversion succeeded.
Again, I apologize for not first asking if C++ is a possibility. (Or even C. The code could be easily done in C.) Also, the result is not quite perfect owing to the JSON GENERATE result being zero filled.

Is it possible to parse a string of fixed length in yacc/lex?

I have a file format something like this
...
{string_length} {binary_string}
...
example:
...
10 abcdefghij
...
Is this possible to parse using lexer/yacc? There is no null terminator for the string, so I'm at a loss of how to tokenize that.
I'm currently using ply's lexer and yacc for this
You can't do it with a regular expression, but you can certainly extract the lexeme. You're not specific about how the length is terminated; here, I'm assuming that it is terminated by a single space character. I'm also assuming that yylval has some appropriate struct type:
[[:digit:]]+" " { unsigned long len = atol(yytext);
yylval.str = malloc(len);
yylval.len = len;
for (char *p = yylval.str; len; --len, ++p) {
int ch = input();
if (ch == EOF) { /* handle the lexical error */ }
*p = ch;
}
return BINARY_STRING;
}
There are other solutions (a start condition and a state variable for the count, for example), but I think the above is the simplest.

How to convert long long to 8 byte array in objective C

In my application i have to convert long long number into 8 byte array. Then i have to convert 8 byte array into hexadecimel string. Can you please help me in this. i'm struck up.
One way to do integer/byte array conversion is to use a union:
union {
long long l;
uint8_t b[sizeof(long long)];
} u;
u.l = mylonglong;
Then u.b[] contains the bytes, which can be accessed individually.
EDIT: Please note as pointed out by #NikolaiRuhe this use of union can lead to undefined behaviour, so it might be best to use memcpy() instead:
uint8_t b[sizeof(long long)];
memcpy(b, &mylonglong, sizeof(b));
If you want the hex string of the long long in native-endian order, then:
void hexChar(uint8_t b, char *out)
{
static const char *chars = "0123456789abcdef";
out[0] = chars[(b >> 4) & 0xf];
out[1] = chars[b & 0xf];
}
// Make sure outbuf is big enough
void hexChars(const uint8_t *buffer, size_t len, char *outbuf)
{
for (size_t i = 0; i < len; i++)
{
hexChar(buffer[i], outbuf);
outbuf += 2;
}
*outbuf = '\0';
}
and call it with:
char hex[32];
hexChars(u.b, sizeof(u.b), hex);
However if instead you want the hex value of the long long:
char hex[32];
sprintf(hex, "%llx", mylonglong);
would that do the trick ?
#include <stdio.h>
int main() {
long long int val = 0x424242;
char str_val[32];
snprintf(str_val, sizeof(str_val), "%#llx", val);
printf("Value : %s\n", str_val);
}

C Programming: Linked Lists

I'm writing a program using linked list (such a nightmare).
Anyway, the purpose of the program is to enter 8 characters and have the program print the characters back out to you and also print the characters back out in reverse order, using linked lists of course.
I got this so far. There's a lot wrong with it (i think).
Problems are
When asking for characters from the user it should read in the amount of characters automatically without having to ask for how many characters
Also, when it it compiles it prints gibberish to the screen, for example I just ran it and it printed
¿r
(àõ($ê¿¿
a¿r
(àõ($ê¿¿
¿r
(àõ($ê¿¿
b¿r
(àõ($ê¿¿
Lots of help needed here. It would be so much appreciated!
Code of course
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define strsize 30
typedef struct member
{
int number;
char fname[strsize];
struct member *next;
}
RECORD;
RECORD* insert (RECORD *it);
RECORD* print(RECORD *it, int j);
int main (void)
{
int i, result;
RECORD *head, *p;
head=NULL;
printf("Enter the number of characters: ");
scanf("%d", &result);
for (i=1; i<=result; i++)
head=insert (head);
print (head, result);
return 0;
}
RECORD* insert (RECORD *it)
{
RECORD *cur, *q;
int num;
char junk;
char first[strsize];
printf("Enter a character:");
scanf("%c", &first);
cur=(RECORD *) malloc(sizeof(RECORD));
strcpy(cur->fname, first);
cur->next=NULL;
if (it==NULL)
it=cur;
else
{
q=it;
while (q->next!=NULL)
q=q->next;
q->next=cur;
}
return (it);
}
RECORD* print(RECORD *it, int j)
{
RECORD *cur;
cur=it;
int i;
for(i=1;i<=j;i++)
{
printf("%s \n", cur->fname);
cur=cur->next;
}
return;
}
You have:
in insert:
char first[strsize];
scanf("%c", &first); /* note the %c */
strcpy(cur->fname, first);
in print
printf("%s \n", cur->fname);
You should have %s instead of %c and therefore change &format to format in the argument list, as format itself represents the address of the location the string is to be stored.
So the scanf call should be like below
scanf("%s", first);
Another thing. If you have specified a return type in the print function then you should return something, or make it return nothing (declare return type as void). This will not pose any problem in this case although.
Read the warning messages which the compiler throws to you and you would see the compiler actually had answered your questions.
You need to do some redesigns i think. For example to traverse the linked list you do not need to counter 'j'. you can detect the list termination by inspecting if the next link is NULL or not.
Your question was to print the characters or strings in reverse, so you need to write some other print function than what you have wrote.

sysctlbyname for kern.osrelease returns NULL

Here is my code and I am trying to get OSVersion here on IOS devices. And that warning is at line return ret; ----> Incompatible integer to pointer conversion returning 'char' from a function with result type 'char *'; take the address with &. When I change ret to &ret it still doesn't work.
char *getOSVersion() {
char str[256];
size_t size = sizeof(str);
char ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
return ret;
}
It seems that sysctlbyname returns integer value and you try to return locally created char pointer from your function. I think you should either take your char pointer as a parameter and assign it in function body or you should return char by value.
Try using in this way;
char getOSVersion() {
char str[256];
size_t size = sizeof(str);
char ret = (char)sysctlbyname("kern.osrelease", str, &size, NULL, 0);
return ret;
}
In the code you posted you are returning the result of the sysctl call (error code) instead of the actual string returned by it.
Probably you meant return str; in the last line?
your code:
char *getOSVersion() {
char str[256];
size_t size = sizeof(str);
char ret = sysctlbyname("kern.osrelease", str, &size, NULL, 0);
return ret;
}
Analysis
char *getOSVersion() { is your function definition -> means return value type is char *
but your implementation return ret; means return type is char
so: char * != char
Soluton
according to your code, seems you want to return os version string
and the os version value returned by sysctlbyname is stored inside str
so you need change return ret; to return str;
Updated code could be:
char *getOSVersion() {
char osVersonStrBuffer[256];
size_t size = sizeof(str);
int retErrorNumber = sysctlbyname("kern.osrelease", osVersonStrBuffer, &size, NULL, 0);
return storeReturnValueStr;
}
Related doc: (apple's sysctlbyname)[https://developer.apple.com/documentation/kernel/1387446-sysctlbyname]

Resources