"assignment makes integer from pointer without a cast " warning in c - c

#include<stdio.h>
/* this is a lexer which recognizes constants , variables ,symbols, identifiers , functions , comments and also header files . It stores the lexemes in 3 different files . One file contains all the headers and the comments . Another file will contain all the variables , another will contain all the symbols. */
int main()
{
int i=0,j;
char a,b[20],c[30];
FILE *fp1,*fp2;
c[0]='"if";
c[1]="then";
c[2]="else";
c[3]="switch";
c[4]="printf";
c[5]="scanf";
c[6]="NULL";
c[7]="int";
c[8]="char";
c[9]="float";
c[10]="long";
c[11]="double";
c[12]="char";
c[13]="const";
c[14]="continue";
c[15]="break";
c[16]="for";
c[17]="size of";
c[18]="register";
c[19]="short";
c[20]="auto";
c[21]="while";
c[22]="do";
c[23]="case";
fp1=fopen("source.txt","r"); //the source file is opened in read only mode which will passed through the lexer
fp2=fopen("lext.txt","w");
//now lets remove all the white spaces and store the rest of the words in a file
if(fp1==NULL)
{
perror("failed to open source.txt");
//return EXIT_FAILURE;
}
i=0;
while(!feof(fp1))
{
a=fgetc(fp1);
if(a!=' ')
{
b[i]=a;
}
else
{
for (j=0;j<23;j++)
{
if(c[j]==b)
{
fprintf(fp2, "%.20s\n", c[j]);
continue ;
}
b[i]='\0';
fprintf(fp2, "%.20s\n", b);
i=0;
continue;
}
//else if
//{
i=i+1;
/*Switch(a)
{
case EOF :return eof;
case '+':sym=sym+1;
case '-':sym=sym+1;
case '*':sym=sym+1;
case '/':sym=sym+1;
case '%':sym=sym+1;
case '
*/
}
fclose(fp1);
fclose(fp2);
return 0;
}
This is my c code for lexical analysis .. its giving warnings and also not writing anything into the lext file ..

char c[30]; declares an array of 30 char, i.e. 30 byte long chunk of memory. So an assignment like the c[0] = "if"; tries putting a pointer into a char-sized integer.
What you probably want there is char* c[30]; - an array of 30 pointers.

C does not support assignment of arrays - you cannot say things like:
c[0]='"if";
in C. And there seems to be an extraneous quote in your code.
All your posts here this afternoon have been on really basic stuff. Which C textbook are you using where this kind of thing is not covered?

As I've said here (another question of yours),
c is a char*, while c[0], c[1], c[2], ... are char.
What you are trying to do, is to assign a char* (eg. "if") to a char (eg. c[0]).

Also you are comparing strings as:
if(c[j]==b)
you should be using strcmp for this as:
if(! strcmp(c[j],b))
Its sad that you've not followed any of the suggestions on your previous question.

Related

Pointers and char arrays from strings

Hi I have been reading for hours and still can't grasp the conversions between
{
char i ="adf";
char foo[];
char bar[256];
}
and adding * and & makes it more confusing
I have some code that is working.
int TX_SEND(char send[])
{
unsigned char *p_tx_buffer;
p_tx_buffer = &send[0];
strcat(send, "\r");
// Write to the port
int n = write(fd,&send[0],3);
if (n < 0) {
perror("Write failed - ");
return -1;
}
return(0);
}
code is working but I need help with 2 parts.
I want to be able to run this function like kind of like printf IE TX_SEND("AT+CGMSD=STUFF"); but I am stuck
but before hand I do this alot.
char txsend[] = "at";
TX_SEND(txsend);
Also inside my TX_WRITE() I am using write(fd,&send[0],3), but it is hardcoded to send 3 bytes from send[]. I want this to be dynamic so I can just send strings at any length (realistically they will be less than 300 ASCII chars always). I tried to do something with a pointer in there but gave up (*p_tx_buffer was my beginning attempt).
i think you want
int TX_SEND(char *send)
{
int n = write(fd,send,strlen(send));
if (n < 0) {
perror("Write failed - ");
return -1;
}
return(0);
}
you cannot tack on \n to send with strcat. I would add it in the calling function, or declare an intermediate buffer and sprintf to it
like this
int TX_SEND(char *send)
{
char buff[50]; // i dont know a good max size
snprintf(buff, sizeof(buff), "%s\n", send);
int n = write(fd,buff,strlen(buff));
if (n < 0) {
perror("Write failed - ");
return -1;
}
return(0);
}
I'm not going to go through your code line-by-line, but I urge you to focus on these facts:
chars are chars and strings are strings, and never the twain shall meet. (They're totally different.)
'x' is a character constant.
"x" is a string constant.
A string is an array of characters (terminated by '\0').
When you mention an array (including a string) in a context where you need its value, what you get is a pointer to the array's first element.
When you put a & in front of something, what you get is a pointer to that something.
When you put a * in front of a pointer, what you get is the thing that the pointer points to.
Putting this together, we could write
char str[] = "xyz";
char *p = str; /* per rule 5, this is fine, and p gets a pointer to str's first element */
char c = *p; /* per rule 7, c gets the first character of str, which is 'x' */
printf("%c\n", c);
If you're just starting with C, you may not have come across rule 5 yet. It will probably surprise you at first. Learn it well, though: you'll never understand arrays and pointers in C without it.

C Programming - Trouble with pointers, no console output

After getting moderately comfortable with Java, i'm now trying to expand my horizon and try my hand at C programming. However, I cannot seem to wrap my head around the pointers in C, even with having visited multiple videos and websites.
The code below is supposed to take in two strings from the user, get the length of both of them and then compare the lengths against one another. The program should then return the longest of the two names (taking great care to return the length until newline, not the allocated size for the variable) by means of a pointer. So, when the user inputs 'Peterson'(name1) and 'Thisisareallylonglastname'(name2) the program should return 'Thisisareallylonglastname' by means of the pointer / name2 connection.
The problem I am having is that when trying to run the code (written in the Eclipse Neon C/C++ IDE, using the MinGW compiler) I get no output in the console. I am fairly certain I have set the path to my MinGW install correctly in windows, but to be sure I have also added the enviroment manually to the project. Between my confusion for pointers and generally being a crappy coder I am not sure what the (undoubtedly novice) mistake with my program is. I am not getting errors of any kind in the Neon IDE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1:");
printf(size1);
int size2 = strlen(name2);
printf("Length of name 2:");
printf(size2);
if (size1 > size2)
{
ch = &name1;
}
else
{
ch = &name2;
}
if(!ch)
{
printf("The largest family name found is:");
printf(*ch);
}
return(0);
}
One major problem is that your final output is under the condition if (!ch) - which, in English, reads "if the pointer ch is null-valued". Since it points to one of two (non-null) memory locations, this check will never pass.
If you change that to if (ch) (or just omit the check, since we know it's not null) and fix the printf problems pointed out by others in the comments, I think you'll get better results.
A pointer to char and an array of char are both ways of representing strings in C and as such are the same type. The main difference being that with the array the memory is allocated at compile time and with a pointer you either assign an array to it (like you're trying to do) or dynamically allocate the memory.
So when you're doing
ch = &name1;
What you're actually doing is trying to assign a pointer to the string name1 to ch, which isn't the same type and should throw up an error. Instead you really want to be doing
ch = name1;
Conversely, *ch is the same as ch[0] - you're accessing the first character of the string so to print it out you want to have
printf("%s",ch);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1: %d", size1);
int size2 = strlen(name2);
printf("Length of name 2: %d", size2);
if (size1 > size2)
{
ch = name1;
}
else
{
ch = name2;
}
printf("The largest family name found is: %s", ch);
return(0);
}
This should do the trick. You should also use scanf("%s", str) instead of gets.
When you do char name1[256] name1 is "considered an pointer", so you must do ch = name1 not ch = &name1, because both ch and name1 are pointers.
when you did:
if(!ch)
{
printf...
}
you will only print if the ch is null, wich you don't want, because, in this case, you want to print if ch has a value so you should do:
if(ch)
{
printf...
}
also in c printf must receive the information about the variable you are trying to print, check printf examples to understand it
The main problem is that you're expecting printf to act as a polymorphic function like System.out.println, and it doesn't. The prototype for printf is
int printf( const char * restrict format, ... );
The first argument is always a character string; the string may contain conversion specifiers that control how any additional arguments are formatted.
So instead of writing:
printf("Length of name 1:");
printf(size1);
you'd write:
printf( "Length of name 1: %d\n", size1 );
or
printf( "Length of name 1: " );
printf( "%d\n", size1 );
The %d in the format string tells printf that the corresponding argument should have type int, and that you want to display its value as a string of decimal digits. See the online C 2011 standard, section 7.21.6.1, for the complete list of conversion specifiers.
printf doesn't automatically append a newline to all output the way System.out.println does - you have to specify it in the format string (\n).
Standard output is typically line buffered - output won't show up on the console until a) the buffer is full, b) the buffer is manually flushed with fflush, c) a newline appears in the buffer, or d) an input function (fgets, scanf, etc.) immediately follows the output function.
Array semantics in C and Java are wildly different. In C, arrays are not reference objects - they don't point to dynamically-allocated memory on the heap. However, the array subscript operation a[i] is defined in terms of pointer arithmetic - *(a + i). What happens in C is that when an array expression is not the operand of the sizeof or unary & operators, or isn't a string literal used to initialize an array in a declaration, the expression is converted ("decays") from type "N-element array of T" to "pointer to T", and the value of the expression is the address of the first element of the array.
This is a very long-winded way of saying that instead of writing
ch = &name1;
you should be writing
ch = name1;
instead. The expression name1 "decays" to a pointer to the first element of the array, and the resulting type of the expression is char *. The type of the expression &name1 is char (*)[256] (pointer to 256-element array of char), which is not what you want. They'll both evaluate to the same location (modulo any type conversions), but type matters.
Finally...
NEVER NEVER NEVER NEVER NEVER use gets. It will introduce a point of failure / major security hole in your code. It was deprecrated shortly after the release of the C99 standard, and has been officially removed from the standard library in C2011. That one library function has been responsible for untold amounts of mayhem over the decades. Do not use it, not even in toy code. It is the "Highlander II" of the C programming language - it never existed. Use fgets instead.

A dilemma with reading files in C

Its my first question, so I hope you guys can help. In class, I was tasked with writing a C code that reads a group of strings from 1 file, and print them in another file, along with the ASCII codes of each character in the string, and the sum of the ASCII code values. The code below compiled, but did not execute. Is the code right, but I did something wrong, or is the code simply wrong. Thanks a bunch.
Note: the first file reads from a text file named list, and the code prints into a text document named list2.
#include <stdio.h>
int main(void)
{
FILE *file1, *file2;
file1 = fopen("list.txt", "r");
if (file1==NULL)
{
puts(" File not exisiting\n");
}
file2 = fopen("list2.txt", "w");
if (file2==NULL)
{
puts(" File could not open \n");
}
char a[5];
fscanf(file1, "%s", a);
int b,c;
while (a[5]!=EOF)
{
for (int i=0;i<5;i++)
{
fprintf(file2, "%c", a[i]);
b=a[i];
fprintf(file2, "%d", b);
c+=b;
}
}
fprintf(file2, "%d", c);
return 0;
}
Point 1. With a definition like
char a[5];
using
while (a[5]!=EOF)
invokes undefined behaviour.
You're facing off-by-one error. Remember, array index in c starts from 0. The valid access it at most upto a[4].
Point 2. fscanf(file1, "%s", a); is unsafe. It can cause buffer overflow. Atleast, you need to write
if ( fscanf(file1, "%4s", a) != 1)
{
//scanning not successful, take necessary measures
}
//otherwise, continue nomal execution.
Point 3. The logic for while loop is not correct. You don't have a break condition there.
Point 4. c+=b;, here c is used uninitalized. read-before-write scenario. Again, undefined behaviour. Remember, auto local variables doesnot get initialized to 0 or some value automatically. You've to initialize explicitly.
Point 5. Do not continue normal execution if if (file1==NULL) condition satisfies. Only printing a message is not sufficient. You should discontinue the program and avoid using file1, file1 etc.
Credits for point 5: user4402433
Include return in the file check as
if (file1==NULL)
{
puts(" File not exisiting\n");
return 0;
}
as there is no use of proceeding with the code if any one of the file is opened.
Also initialize the value of c=0; before while so that any garbage value can be avoided.
The array a[] has to be indexed to update the file content. So place the
fscanf(file1, "%s", a[i]);
inside the for() loop . This is to avoid buffer overflow which occurs in rare cases.

C: simultaneous reading from and writing to file

What i would like to do:
Read bits from one file (input file), and write these (with some probability) inverted bits to other file (output file).
What is the problem:
Probability idea seem not to be working properly. And more importantly, output file always contains more characters then the original input file, while they should contain equal number of characters.
In this code sample, instead of inverted bits i have put 'x' and 'y', so that it is more obvious that output file contains more characters
INPUT file: 01001
OUTPUT file: xyxxxyx
The code:
void invert_bits(FILE **input, FILE **output, double prob){
srand(clock());
char symbol;
while((symbol = getc(*input)) != EOF){
double result = rand()/RAND_MAX;
if(result < prob){
if(simbol == '0'){
char bit = 'x';
fprintf(*output, &bit);
}
else{
char bit = 'y';
fprintf(*output, &bit);
}
}else{
fprintf(*output, &symbol);
}
}
}
(f)printf expects a format string as its second argument. You are providing it with the address of a char, which is not even a valid string (since it is not NUL-terminated).
Don't do that. It's a bad habit. When you use printf, fprintf or sprintf always use a format string. (Read this for more information.)
You could have used fprintf(*output, "%c", bit); but it would be a lot simpler to just print the character with fputc(bit, *output);
I don't understand why you feel the need to pass the FILE* arguments as pointers, by the way.
You aren't using the fprintf function properly.
The function's signature is:
int fprintf ( FILE * stream, const char * format, ... );
Instead of a null terminated string, you're providing it with an address of a char, which might follow by a null character, or might not.
The correct way of printing a character with the *printf functions is:
fprintf(*output, "%c", bit);
P.S. Why are you receiving a pointer to the file handle, i.e. FILE** and not just FILE*?

printf() isn't being executed

I wanted to write a program which counts the occurrences of each letter in a string, then prints one of each letter followed by the count for that letter.
For example:
aabbcccd -
Has 2 a, 2 b, 3 c, and 1 d
So I'd like to convert and print this as:
a2b2c3d1
I wrote code (see below) to perform this count/conversion but for some reason I'm not seeing any output.
#include<stdio.h>
main()
{
char array[]="aabbcccd";
char type,*count,*cp=array;
while(cp!='\0'){
type=*cp;
cp++;
count=cp;
int c;
for(c=1;*cp==type;c++,cp++);
*count='0'+c;
}
count++;
*count='\0';
printf("%s",array);
}
Can anyone help me understand why I'm not seeing any output from printf()?
char array[]="aabbcccd";
char type,*count,*cp=array;
while(cp!='\0'){
*cp is a pointer it's pointing to the address of the start of the array, it will never be == to a char '\0' so it can't leave the loop.
You need to deference the pointer to get what it's pointing at:
while(*cp != '\0') {
...
Also, you have a ; after your for loop, skipping the contents of it:
for(c=1;*cp==type;c++,cp++); <-- this ; makes it not execute the code beneath it
After fixing both of those problems the code produces an output:
mike#linux-4puc:~> ./a.out
a1b1c2cd
Not the one you wanted yet, but that fixes your problems with "printf not functional"
Incidentally, this code has a few other major problems:
You try to write past the end of the string if the last character appears once (you write a '1' where the trailing '\0' was, and a '\0' one character beyond that.
Your code doesn't work if a character appears more than 9 times ('0' + 10 is ':').
Your code doesn't work if a character appears more than 2 times ("dddd" doesn't become "d4"; it becomes "d4dd").
Probably line-buffering. Add a \n to your printf() formatting string. Also your code is very scary, what happens if there are more than 9 of the same character in a row?
1) error correction
while(*cp!='\0'){
and not
while(cp!='\0'){
2) advice
do not use array[] to put in your result user another array to put in your rusel it's more proper and eay
I tried to solve your question quickly and this is my code:
#include <stdio.h>
#define SIZE 255
int main()
{
char input[SIZE] = "aabbcccd";/*input string*/
char output[SIZE]={'\0'};/*where output string is stored*/
char seen[SIZE]={'\0'};/*store all chars already counted*/
char *ip = input;/*input pointer=ip*/
char *op = output;/*output pointer = op*/
char *sp = seen;/*seen pointer=sp*/
char c,count;
int i,j,done;
i=0;
while(i<SIZE && input[i]!='\0')
{
c=input[i];
//don't count if already searched:
done=0;
j=0;
while(j<SIZE)
{
if(c==seen[j])
{
done=1;
break;
}
j++;
}
if(done==0)
{//if i never searched char 'c':
*sp=c;
sp++;
*sp='\0';
//count how many "c" there are into input array:
count = '0';
j=0;
while(j<SIZE)
{
if(ip[j]==c)
{
count++;
}
j++;
}
*op=c;
op++;
*op=count;
op++;
}
i++;
}
*op='\0';
printf("input: %s\n",input);
printf("output: %s\n",output);
return 0;
}
It's not a good code for several reasons(I don't check arrays size writing new elements, I could stop searches at first empty item, and so on...) but you could think about it as a "start point" and improve it. You could take a look at standard library to copy substring elements and so on(i.e. strncpy).

Resources