Define header filename as variable in Arduino/C - c

In arduino IDE i want to define a filename as variable. Then insert it into a header for uploading a file to a flask application as variable.
Filename should be as example: 1
Hardcoding the filename as following works well:
if (https.begin(*client, "https://hanspeter//")) {
https.addHeader("Content-Type", "image/jpeg");
https.addHeader("Content-Disposition", "inline; filename=\"1\"");
I tried different options to define a variable, but always get errors:
Option 1:
const char *thisisaname = "1";
https.addHeader("Content-Disposition", "inline; filename="thisisaname);
Error:
unable to find string literal operator 'operator""thisisaname' with 'const char [18]', 'unsigned int' arguments
Option 2.
const char *thisisaname = "1";
https.addHeader("Content-Disposition", "inline; filename=\"" + thisisaname + "\""));
Error:
invalid operands of types 'const char [19]' and 'const char*' to binary 'operator+'
Option 3.
const char *thisisaname = "\"1\"";
https.addHeader("Content-Disposition", "inline; filename="thisisaname);
Error:
invalid operands of types 'const char [19]' and 'const char*' to binary 'operator+'

The normal way of doing that would be a #define. It is memory efficient and won't take up much flash. Then you can also take advantage of string literal concatenation:
#define SO "http://stackoverflow.com/"
#define URL "questions"
...
surf_to(SO URL)
which expands to surf_to("https://stackoverflow.com/questions")

Related

assignment to 'char' from 'const char *' makes integer from pointer without a cast

I am very new to C and am encountering an issue while trying to store my next_frame in a variable. Any help would be great as I think this is probably something simple I'm just missing.
If I just change the following it works fine, only when I try to store the next_frame in a variable does it not compile.
// Doesn't compile
oled_write_raw_P(next_frame, FRAME_SIZE);
// Compiles
oled_write_raw_P(frames[abs((FRAME_COUNT - 1) - current_frame)];, FRAME_SIZE);
Full Code
#define FRAME_COUNT 5 // Animation Frames
#define FRAME_SIZE 256
#define FRAME_DURATION 200 // MS duration of each frame
// Variables
uint32_t timer = 0;
uint8_t current_frame = 0;
char next_frame;
static void render_animation(void) {
static const char PROGMEM frames[FRAME_COUNT][FRAME_SIZE] = {
// Images here, removed for example
};
// If timer is more than 200ms, animate
if (timer_elapsed32(timer) > FRAME_DURATION) {
timer = timer_read32();
current_frame = (current_frame + 1) % FRAME_COUNT;
next_frame = frames[abs((FRAME_COUNT - 1) - current_frame)];
// Set cursor position
oled_set_cursor(128, 0);
// Write next frame
oled_write_raw_P(next_frame, FRAME_SIZE);
}
}
These are the errors:
error: assignment to 'char' from 'const char *' makes integer from pointer without a cast [-Werror=int-conversion]
next_frame = frames[abs((FRAME_COUNT - 1) - current_frame)];
error: passing argument 1 of 'oled_write_raw_P' makes pointer from integer without a cast [-Werror=int-conversion]
oled_write_raw_P(next_frame, FRAME_SIZE);
The line
next_frame = frames[abs((FRAME_COUNT - 1) - current_frame)]
does not make sense.
The variable next_frame, to which you are assigning a value, has the type char. However, you are assigning it the expression
frames[abs((FRAME_COUNT - 1) - current_frame)]
which decays to a pointer to the first element of the sub-array, so the expression evaluates to a value of type const char *.
I'm not exactly sure what you want to accomplish, but I guess the solution to your problem is to change the type of next_frame to const char *, so that the types match. In order to do this, you can change the line
char next_frame;
to:
const char *next_frame;

Why do I get "assigning to 'int *' from incompatible type 'void *' " error?

I'm learning c on codeacademy and I get an assigning to 'int *' from incompatible type 'void *' error. My file is a .c file, which includes stdlib.h. I don't understand the error, it seems that the corrections uses the same lines of code.
I'm trying to create an array using malloc.
I tried to find the answer on other topics. It seems that malloc is not the best way to do it but i would like to find a way to make it work.
I'm on a mac, I use emacs to code et gcc to compile.
Here's a part of my code :
int main(int argc, char *argv[])
{
char mot_secret[] = "PISCINE";
int nombre_lettres = strlen(mot_secret);
int *pnombre_lettres = &nombre_lettres;
int *decouverte = NULL;
int compteur = 10;
decouverte = malloc(nombre_lettres * sizeof(int));
if (decouverte == NULL)
{
exit(0);
}
And here's the solution :
( I tried to translate some of the variables)
int main(int argc, char* argv[])
{
char lettre = 0;
char secretword[100] = {0};
int *lettreTrouvee = NULL;
long coupsRestants = 10; // Compteur de coups restants (0 = mort)
long i = 0;
long wordSize = 0;
wordSize = strlen(secretWord);
lettreTrouvee = malloc(tailleMot * sizeof(int)); // creates a dynamic array of the size of the original)
if (lettreTrouvee == NULL)
exit(0);
The error is :
TP.C:17:16: error: assigning to 'int *' from incompatible type 'void *'
decouverte = malloc(nombre_lettres * sizeof(int));
Thank you very much for your help and I'm sorry if I make any mistakes in English.
It appears that your file's name is TP.C.
In the unix tradition, C source files are named *.c (lowercase c), and C++ source files are named *.C (capital C). The alternative *.cpp is used on Windows because of its case-ignorant filesystem, but gcc on MacOS is sufficiently unix-like that it is treating your *.C file as C++.
Given this error message:
TP.C:17:16: error: assigning to 'int *' from incompatible type 'void *'
decouverte = malloc(nombre_lettres * sizeof(int));
it appears your file is named TP.C. The upper-case .C file extension causes GCC to compile the file as C++:
file.cc
file.cp
file.cxx
file.cpp
file.CPP
file.c++
file.C
C++ source code that must be preprocessed. Note that in ‘.cxx’, the last two > must both be literally ‘x’. Likewise, ‘.C’ refers to a literal capital C.
You need to use lower-case. Rename your file so that it ends with a .c - lower-case c.
The type returned from malloc is always void*, which can be cast to the desired type of data.
You will need to do:
(int*) malloc(nombre_lettres * sizeof(int));
source: cplusplus

Warning passing 'char []' to parameter of type 'unsigned char *'

I am working on Keil Compiler for ARM controllers and writing code in C. I am stuck with this warning I am getting this :
warning : passing 'char [7]' to parameter of type 'unsigned char *'converts between pointers to integer types with different sign.
Routine :
void WriteString(unsigned char *Msg_add)
{
for(Lcd_pointer=0; Lcd_pointer < 16; Lcd_pointer++)
{
Write_lcd_data(*Msg_add);
Msg_add++;
if(*Msg_add == '\0')
break;
}
}
I am passing above routine with random string :
WriteString("Token:");
The fucntions works by the way, But I am getting this warning. How to remove?
This is the expected warning as "Token:" is of type const char *
but void WriteString(unsigned char *Msg_add) is expecting unsigned char *
You need to type cast the argument
WriteString((unsigned char*) your_data);

Converting string to long using strtol and pointers

My goal is to convert a string such as "A1234" to a long with value 1234. My first step was to just convert "1234" to a long, and that works as expected:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char* test = "1234";
long val = strtol(test,NULL,10);
char output[20];
sprintf(output,"Value: %Ld",val);
printf("%s\r\n",output);
return 0;
}
Now I am having trouble with pointers and trying to ignore the A at the beginning of the string. I have tried char* test = "A1234"; long val = strtol(test[1],NULL,10); however that crashes the program.
How do I set this up properly to get it pointing to the correct spot?
You are almost right. You need to pass a pointer to strtol, though:
long val = strtol(&test[1], NULL, 10);
or
long val = strtol(test + 1, NULL, 10);
Turning on some compiler warning flags would have told you your problem. For example, from clang (even with no special flags added):
example.c:6:23: warning: incompatible integer to pointer conversion passing
'char' to parameter of type 'const char *'; take the address with &
[-Wint-conversion]
long val = strtol(test[1],NULL,10);
^~~~~~~
&
/usr/include/stdlib.h:181:26: note: passing argument to parameter here
long strtol(const char *, char **, int);
^
1 warning generated.
and from GCC:
example.c: In function ‘main’:
example.c:6: warning: passing argument 1 of ‘strtol’ makes pointer from integer
without a cast
Editorial note: I think you can see from these error messages why beginners are often well-advised to use clang rather than GCC.

C : Working with structures and pointers , error : invalid type argument of unary ‘*’

I'm working on a c program and here is the structure I am using
struct EngineParts{
int serial_number;
unsigned int year_of_manufacture;
unsigned int quantity;
char *material;
}*Eparts;
And I am getting the following error
`Automobile.c:79:5: error: invalid type argument of unary ‘*’ (have ‘unsigned int’)`
`Automobile.c:80:5: error: invalid type argument of unary ‘*’ (have ‘int’)`
`Automobile.c:81:5: error: invalid type argument of unary ‘*’ (have ‘unsigned int’)`
in these three lines
*new->quantity = quantity;
*new->serial_number = serial_number;
*new->year_of_manufacture = year_of_manufacture;
Here is the complete implementation
void automobile_add_part(const int serial_number,
const unsigned int year_of_manufacture,
const unsigned int quantity ,
const char *material){
/*
* Store the address to the latest part
*/
struct EngineParts *new ;
new = (Eparts+available_number_of_parts);
// Copying a String is a little bit complicated
// First memory is allocated for the string
*new->material = (char *)calloc(strlen(material),sizeof(char));
//Then the string is copied
strcpy((char *)*new->material,material);
*new->quantity = quantity;
*new->serial_number = serial_number;
*new->year_of_manufacture = year_of_manufacture;
available_number_of_parts++;
}
PS :
I have checked out the following questions ,
error: invalid type argument of ‘unary *’ (have ‘int’)
Invalid type argument of -> C structs
but they don't seem to help me.
Any suggestions on how to solve the problem ?
The -> operator already dereferences the pointer for you.
new->serial_number is equivalent to (*new).serial_number, both of which seem like what you want.
Do it this way:
new->quantity = quantity;
The extra pointer dereference (*new->quantity) is an error: new->quantity is an int, not any kind of pointer so the compiler complains.
Dereferencing the new pointer (is it even legal to have a variable named such?) is already done through operator->.
The -> operator dereferences the pointer, so use of additional * is not required. And results in error.
no need * for new->quantity
the -> is shortcut for (*new).quantity

Resources