Difference between scanf for char * and char [ ]? - c

I'm a newbie to c programming. I'm trying to input two strings using scanf. My first try was as below
#include <stdio.h>
int main(void)
{
char *word1;
char *word2;
scanf("%s", word1);
scanf("%s", word2);
printf("%s\n", word1);
printf("%s\n", word2);
}
If I run this code, only the first input is correctly stored (word2 is null). But, if I run the code below, both inputs are correctly stored in word1 and word2.
#include <stdio.h>
int main(void)
{
char word1[10];
char word2[10];
scanf("%9s", word1);
scanf("%9s", word2);
printf("%s\n", word1);
printf("%s\n", word2);
}
What is the problem with using pointers with scanf?

There is no problem in with using a pointer as your scanf argument in principle. In your specific case, you've simply not initialized those pointers, so you're causing undefined behaviour. Modifying your second (correct) example to use pointers:
#include <stdio.h>
int main(void)
{
char word1[10];
char *p1 = word1;
char word2[10];
char *p2 = word2;
scanf("%9s", p1);
scanf("%9s", p2);
printf("%s\n", p1);
printf("%s\n", p2);
}
The important thing to remember about pointers is that they have to point to something in order to be useful.

What is the problem with using pointers with scanf?
The first one is undefined behaviour. Look at this part of code:
char *word1;
char *word2;
scanf("%s", word1);
scanf("%s", word2);
No memory allocated to word1 and word2 pointers. When you give input, scanf() end up accessing unallocated pointers and dereferencing an unallocated/invalid pointer is undefined behaviour.
You should make sure that before using/accessing a pointer, it should be pointing to a valid memory location. You can either make it point to an exiting valid memory or allocate memory dynamically to it, like this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *word1;
char *word2;
word1 = malloc (10);
if (word1 == NULL) {
exit (EXIT_FAILURE); // or whatever you want to do to handle memory allocation failure
}
word2 = malloc (10);
if (word2 == NULL) {
exit (EXIT_FAILURE); // or whatever you want to do to handle memory allocation failure
}
scanf("%9s", word1);
scanf("%9s", word2);
printf("%s\n", word1);
printf("%s\n", word2);
// once done with allocated memory, free it
free (word1);
free (word2);
return 0;
}

Related

How do I use a string variable in the printf() function in c?

I am running the following c program:
#include <stdio.h>
int main() {
char str1;
printf("What is your name? ");
scanf("%s.", str1);
printf("Hi there %s.", str1);
return 0;
}
But this what it returns:
What is your name? Varun
Hi there (null).
Why does it say (null)? Please answer.
You have multiple mistakes here:
You use %s for a char variable.
You're not passing a pointer to scanf function. You're just passing a garbage value.
You introduced an undefined behavior. And you should have some compile-warnings that tells you that you have mistakes.
char str1; you have space for only 1 char , that's not much , try replacing with char str1[30]; and try again.
Try this instead:
#include <stdio.h>
int main() {
char str1[1000]; // <-- here are the changes
printf("What is your name? ");
scanf("%s.", str1);
printf("Hi there %s.", str1);
return 0;
}
To use strings in c, you need to create a char array with a specific size
char arr[1000]; // array of size 1000, it can contain a string of 1000 letters
then to fetch the string you have to use
scanf("%s", arr);
then to print it back use
printf("%s", arr);
#include <stdio.h>
#include <malloc.h>
int main() {
char *str;
str = (char *)malloc(sizeof(char) * 10);
printf("What is your name?");
scanf("%s", str);
printf("Hi there %s.", str);
return 0;
}
I think you should do like this, you should understand char and string.

Coding a string length function using pointer arithmetic

I'm in a beginner CS class learning C and we were tasked with coding a function to find string length using only string pointers. I have the following code:
#include <stdio.h>
int strlength(char* str);
int main() {
char *str;
int comp;
printf("Please enter the string: ");
scanf("%s", str);
printf("The length of the string is: %d\n", strlength(str));
return 0;
}
int strlength(char *str) {
int length = 0;
while(*str != '\0') {
length++;
str++;
}
return length;
}
I'm not really sure where I'm getting a segmentation fault. I've tried making a second pointer in the strlength function that equals str and incrementing that, but that also gives me a segmentation fault. Any insight would be appreciated!
char *str;
int comp;
printf("Please enter the string: ");
scanf("%s", str);
You should allocate memory in heap ( with malloc ) for *str before scanf. If you dont want to use malloc change it to char[number] so it can allocate memory in stack instead of heap

_strrev function isnt working inside a function, but works outside

I’m trying to get the _strrev function to work but when I put my string into a function it doesn’t seem to work, just when I'm out of the function..
I’m getting so frustrated because I'm not getting anywhere with this..
Here's my code so far
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char *string) {
char *str, temp;
int begin = 0, end = 0;
char word[64];
int jaja = 0;
printf("Your string from the function is %s\n", string);
printf("%s\n", _strrev(&string)); //And why isnt this working
jaja = strlen(string);
printf("Your string has %d characters\n", jaja);
}
int main()
{
char *str;
scanf("%s", &str);
printf("%s\n", _strrev(&str)); //How come this works
reverse("Okay");
getchar();
return(0);
}
So I would love some guidance where my mistake is, I seriously cant find it.
According to MSDN The prototype for _strrev is
char *_strrev(
char *str
);
If you have a char *string you must call it like this :
printf("%s\n", _strrev(string));
In this case
printf("%s\n", _strrev(&string));
you are passing a char**
To answer the question you posted in your code comments:
int main()
{
char *str;
scanf("%s", &str);
printf("%s\n", _strrev(&str)); //How come this works
That works because you're lucky, as your call to scanf() places whatever it reads into the actual memory used for the pointer str, and you're not entering enough data to cause problems. Try entering a really long string when running this program and it won't work as well.
You need to actually have a char buffer to read data into, like this:
int main()
{
char str[256];
scanf("%s", str);
printf("%s\n", _strrev(str));
or
int main()
{
char *str = malloc( 256 );
scanf("%s", str);
printf("%s\n", _strrev(str));
And as pointed out in the comments to the question, you can still overrun your buffer.

array changes when i change parameter

So i have this code in c.It all works fine until i get to the point to read word again.It gets the new word but also the (*A)[size-1] takes the price of the new word.How do i prevent this?
void fuction(char ***A,char ***B,int size)
{
char word[20],word2[20];
printf("Type word .\n");
gets(word);
while(strcmp(word,"0")!=0)
{
printf("Type second word.\n");
gets(word2);
printf("%d",size);
**A=realloc(**A,(size+1)*sizeof(char));
**B=realloc(**B,(size+1)*sizeof(char));
(*A)[size-1]=word;
(*B)[size-1]=word2;
size++;
printf("Type another word to add or 0 to exit.\n");//**it all works fine**
gets(word);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void function(char ***A, char ***B, int *size){
char word[32], word2[32];
printf("Type first word.\n");
scanf("%31s", word);
while(strcmp(word,"0")!=0){
printf("Type second word.\n");
scanf("%31s", word2);
*A =realloc(*A, (*size+1)*sizeof(char*));
*B =realloc(*B, (*size+1)*sizeof(char*));
(*A)[*size]=strdup(word);
(*B)[*size]=strdup(word2);
++*size;
printf("Type another word to add or 0 to exit.\n");
scanf("%31s", word);
}
}
int main(void){
int i, size = 0;
char **w1, **w2;
w1 = w2 = NULL;
function(&w1, &w2, &size);
for(i = 0; i < size; ++i){
printf("%s, %s\n", w1[i], w2[i]);
free(w1[i]);free(w2[i]);
}
free(w1);free(w2);
return 0;
}
Turns out the problem was that i didnt allocate memory for the words in the array.I added these lines and it worked.Thank you for your answers.
(*A)[size-1]=(char*) malloc(31);
(*B)[size-1]=(char*) malloc(31);
This
(*A)[size-1]=word;
(*B)[size-1]=word2;
is not what you think it is.
In c, this means you are assigning the address to the first element of the array word to (*A)[size-1] if you want this to work, provided that you have allocated memory for (*A)[size-1] you should do it this way
strcpy((*A)[size-1], word);
strcpy((*B)[size-1], word2);
You should think about why do you need char ***, generally you wont need more than char **, and don't use gets() use fgets() instead.

What's wrong with this scanf()?

Am I using scanf() in some wrong way?
char *input;
scanf("%s", input);
printf("%s\n", input);
This fails at the run-time.
Declaring a char * only creates a pointer, it does not allocate any memory for the string. You need to allocate memory for input. You can do that dynamically via malloc (and free when done) or you can declare an array of static size like char input[100].
char *input;
This is a pointer. It doesn't point to any memory.
#include <stdlib.h>
#include <stdio.h>
int main()
{
//char *input;
char input[128];
memset(input, 0 ,sizeof(input));
scanf("%s", input);
printf("%s\n", input);
return 0;
}
replace char *input; with char input[1024] = {0};
you should ensure the parameter you pass to scanf points to a buffer which could hold your input

Resources