C - scanf() and then getenv() - c

I'm asking the user which environment variable he want to know and then I scan it with scanf. But it doesnt work for me. Here is my code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
char *value;
char input;
printf("Which variable do you want?\n");
scanf("%s", input);
value = getenv(input);
printf("%s", value);
}
The compiler says:
"Function argument assignment between types "const char*" and "char" ist not allowed"
So i tried to change the input variable to: char const *input
Now there is no compiler error, but when I submit a name, for example "USER", I get a "Segmentation fault (core dumped)" error.

The warning is because here
value = getenv(input);
you pass a char to getenv(), which has the prototype:
char *getenv(const char *name);
Define input as a char array like:
char input[256];
printf("Which variable do you want?\n");
scanf("%255s", input); //specify the width to avoid buffer overflow
Or, you can use dynamically memory allocation (using malloc) if you think 256 is not big enough for your purposes.

When you defined char *input; you satisfy the compiler because your syntax is valid: when calling scanf("%s", input); you are saying you want a string and it should get placed wherever input is.
The problem is input isn't anywhere (initialized) yet... where it points is undefined at the moment; before using any pointer you must make it point somewhere that is valid (and large enough to hold whatever you intend to put there).
There are a few ways you can solve this, but perhaps the easiest is to decide how large the input needs to be and declare a character array, such as: char input[512];. Be aware that this is problematic because if the input exceeds your buffer you will overwrite other memory... but this should get you moving forward for now.

char is a single char.
char *input declares a variable which hold a pointer to a character, but there is no memory for the data. In C, this is a correct behavior. However, sscanf expects that you actually pass a pointer which points to allocated memory (please consider that the function does not return any pointer, so it has no chance of allocating memory for you).
So between declaration and use, please use malloc to allocate memory.

Related

Convert double to char* in C

How can I convert double to char*.
#include <stdio.h>
int main() {
char * buf;
double number = 3.123;
sprintf(buf,"%f",number);
printf("%s",buf);
return 0;
}
This method is does not want to work and I cannot know why.
char* buf declares buf as a character pointer, but does not actually allocate any memory for it. You should declare buf as an array to allocate memory:
char buf[128];
double number = 3.123;
sprintf(buf, "%f", number);
What you probably want is a floating-point to string conversion. What you need is not a char*, but rather an array. The difference is that an array allocates some space for the string, while a pointer is supposed to point to an already existing string, but there is no such string in your code.
Because of this, your code is producing Undefined Behavior (or UB for short), because sprintf() is attempting to write at the address that the buf pointer references. The pointer was not assigned to point to anything, so it is an uninitialized (wild) pointer. This pointer probably contains a random non-sense value and sprintf() is trying to write to it - it won't work, or even worse, will appear to work until you find a problem in a totally different part of the code.
Here is how you should do it:
#include <stdio.h>
int main(void)
{
char buf[100];
double number = 3.123;
sprintf(buf, "%f", number);
printf("%s", buf);
}
First we declare a character array. It can be any length, but for simplicity I chose 100. We can then use this array in a similar way, by writing to it using sprintf().
Now, there may be another problem. It won't show up in this small piece of code, but if you use sprintf() a lot you will notice a lot of bugs if you don't pay attention to the length of the array. The array has only 100 characters, but sprintf() doesn't know that! The function will simply attempt to write past the end of the array, a bug which is called a buffer overflow, yet another case of UB, and also a very common exploit for malicious attacks.
To ease the programmer's life, C has another function that is safer, snprintf(), which works pretty much the same but takes an extra parameter, the maximum length of the array. Here is how it works:
#include <stdio.h>
int main(void)
{
char buf[100];
double number = 3.123;
snprintf(buf, 100, "%f", number);
printf("%s", buf);
}
Even if we tried to write more than 100 characters to the buffer, the function would only write 100 (actually, 99 and a null terminator), and will discard the rest of the contents. This means that, if you pass the correct value for the length of the array, a buffer overflow won't occur.

C reading from a CSV file zeroes displayed after each record [duplicate]

I have written the following piece of code:
int main() {
char arrays[12];
char *pointers;
scanf("%s", arrays);
scanf("%s", pointers);
printf("%s", arrays);
printf("%s", pointers);
return 0;
}
Why does it give an error when I write scanf("%s", pointers)?
char *pointers;
must be initialized. You can not scan string into pointers until you point it to some address. The computer needs to know where to store the value it reads from the keyboard.
int main() {
char arrays[12];
char *pointers = arrays;
scanf("%s", pointers);
printf("%s", pointers);
return 0;
}
Because you're writing to an address in memory that has not been initialized. Writing to memory pointer by an uninitialized pointer invokes undefined behaviour. Either allocate enough memory:
pointers = malloc(256);
if(!pointers)
perror("malloc");
else
scanf("%255s", pointers);
Or declare it as a static array:
char pointers[256];
You should also consider using fgets() instead of scanf().
You may want to read i you are interested in fgets():
Difference between scanf() and fgets()
char *pointers; creates a pointer variable.
pointers is the address pointed to by pointers, which is indeterminate by
default.
*pointers is the data in the address pointed to by pointers, which you cannot do until address is assigned.
Just do this.
char arrays[12];
char *pointers;
pointers = arrays;
scanf("%s",pointers);
pointers is being used without initialisation, like int x; printf("%d\n", x);. You need to make your pointer point to something before using it. Which book are you reading?
pointers is an unitialized pointer. You are not able to write into it. You shall allocate enough memory to store a string, as you did with arrays. With a pointer, it is possible to use dynamic allocation (cf. malloc).
Could you elaborate on the error, i'm not around a compiler right now.
But for scanf and printf to work you must have this at the top of your program:
#include <stdio.h>
#include <stdlib.h>
Both are standard libraries for C. IO contains scanf, I'm fairly sure printf is in the same. But until you know which libraries you need for which functions it doesn't hurt to include both standard libraries for every program. Try to use custom header files as well so you don't need mass #includes for every file.
Don't forget malloc statements for memory allocation.
But I'm unsure what you're attempting to do with your code, please elaborate?

Why attempt to scan in the name produces segmentation fault?

I am new to programming. I typed this simple code and I keep getting this error message. Does anyone know the reason why the compiler stops working? I have checked the compiler settings and clicked auto detect. It still does not work though.
Any suggestion is appreciated. Btw I am new to programming so break it down if explaining something.
#include <sdtio.h>
#include <stdlib.h>
int main()
{
int name;
printf("What is your name?\n");
scanf("%s", name);
printf("Your name is %s", name);
return 0;
}
The problem here is, you're using wrong argument type for a particular format specifier (or we can say, vice-versa). %s expects a pointer to char array as argument, not an int. It invokes undefined behavior.
You need to use a char array to input a string, something like
#define SIZE 32
char name[SIZE] = {0};
and then using %s format specifier will be correct. Something like
scanf("%31s", name); //32-1, reserve one for null-terminator
will do the job.
The %s format specifier expects a pointer to a char (which points to an array of char), but name is an int.
Change name to a character array.
char name[100];

gets and puts to get and print a string

i'm trying to get and print a string with gets and puts but i get a segmentation fault error when i use them togheter.
this is the code i'm trying to get this working. [i type the string "prova" to test it]
int main()
{
char *s;
gets(s);
puts(s);
return 0;
}
if i change "gets" with "scanf" i get the same error.
if i change "puts" with "printf("%s", s)" i get the output.
if i declare char *s = "prova" and then puts(s) i get the output.
i also tried to change char *s; with char s[] but i get the same error.
where i'm i wrong on this? ty very much
i know gets is bad, is just bc i'm writing exercise from "C how to program, fifth edition" by Deitel and Deitel
You have multiple problems with that piece of code. To start with gets have been deprecated since the C99 standard, and in the C11 standard it has been removed. The reason is that it's not very safe, and has no bounds-checking and so can write beyond the bounds of the memory you pass to it leading to buffer overflows.
Secondly, you use the uninitialized local variable s. The value of an uninitialized variable is indeterminate, and will be seemingly random. Using an uninitialized local variable leads to undefined behavior, which often leads to crashes.
Another problem is if you initialize s to point to a literal strings. Literals strings are constant (read-only) arrays of characters, and attempting to write to it will again lead to undefined behavior.
You need to allocate some room for the string:
char s[256];
gets(s);
puts(s);
But gets is bad. (It doesn't know how big your buffer is, so what happens if more than 255 characters are read?)
The most important mistake you have is that you are declaring a char pointer, but you are not reserving the space in memory where the characters will be stored, so you got a pointer that point to some random memory adress that you should'nt use. the "right" thing to do will be:
#include <stdio.h>
#include <stdlib.h>
#define LENGHT 20
int main()
{
char *s;
s=malloc(sizeof(char)*LENGHT); //here you make the pointer point to a memory adress that you can use
gets(s);
puts(s);
free (s);
return 0;
}
But also is strongly recommend to avoid using gets because that function doesn't check for the length of the input, so use fgets instead that allow you to do that, you will only need to set the data stream to stdin.
The code will be:
#include <stdio.h>
#include <stdlib.h>
#define LENGHT 20
int main()
{
char *s;
s=malloc(sizeof(char)*LENGHT);
fgets(s,20,stdin);
puts(s);
free(s);
return 0;
}

using scanf function with pointers to character

I have written the following piece of code:
int main() {
char arrays[12];
char *pointers;
scanf("%s", arrays);
scanf("%s", pointers);
printf("%s", arrays);
printf("%s", pointers);
return 0;
}
Why does it give an error when I write scanf("%s", pointers)?
char *pointers;
must be initialized. You can not scan string into pointers until you point it to some address. The computer needs to know where to store the value it reads from the keyboard.
int main() {
char arrays[12];
char *pointers = arrays;
scanf("%s", pointers);
printf("%s", pointers);
return 0;
}
Because you're writing to an address in memory that has not been initialized. Writing to memory pointer by an uninitialized pointer invokes undefined behaviour. Either allocate enough memory:
pointers = malloc(256);
if(!pointers)
perror("malloc");
else
scanf("%255s", pointers);
Or declare it as a static array:
char pointers[256];
You should also consider using fgets() instead of scanf().
You may want to read i you are interested in fgets():
Difference between scanf() and fgets()
char *pointers; creates a pointer variable.
pointers is the address pointed to by pointers, which is indeterminate by
default.
*pointers is the data in the address pointed to by pointers, which you cannot do until address is assigned.
Just do this.
char arrays[12];
char *pointers;
pointers = arrays;
scanf("%s",pointers);
pointers is being used without initialisation, like int x; printf("%d\n", x);. You need to make your pointer point to something before using it. Which book are you reading?
pointers is an unitialized pointer. You are not able to write into it. You shall allocate enough memory to store a string, as you did with arrays. With a pointer, it is possible to use dynamic allocation (cf. malloc).
Could you elaborate on the error, i'm not around a compiler right now.
But for scanf and printf to work you must have this at the top of your program:
#include <stdio.h>
#include <stdlib.h>
Both are standard libraries for C. IO contains scanf, I'm fairly sure printf is in the same. But until you know which libraries you need for which functions it doesn't hurt to include both standard libraries for every program. Try to use custom header files as well so you don't need mass #includes for every file.
Don't forget malloc statements for memory allocation.
But I'm unsure what you're attempting to do with your code, please elaborate?

Resources